Merge pull request #640 from ueokande/auto-deploy

Deploy an addon automatically
jh-changes
Shin'ya Ueoka 5 years ago committed by GitHub
commit 428805e66f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 38
      .circleci/config.yml
  2. 172
      package-lock.json
  3. 2
      package.json
  4. 91
      script/deploy

@ -47,7 +47,7 @@ commands:
- restore_cache:
key: dependency-cache-{{ checksum "package-lock.json" }}
- run:
name: Install npm wee
name: Install dependencies
command: npm install
- save_cache:
key: dependency-cache-{{ checksum "package-lock.json" }}
@ -77,6 +77,19 @@ jobs:
- run: npm run build
- run: npm run test:e2e
deploy:
executor:
name: default
steps:
- checkout
- setup_npm
- run: npm run package
- run:
name: Deploy to AMO
command: |
version=$(jq -r '.version' manifest.json)
./script/deploy vim-vixen@i-beam.org "$version" "vim-vixen-${version}.zip"
workflows:
version: 2
build_and_test:
@ -86,3 +99,26 @@ workflows:
filters:
branches:
ignore: /^greenkeeper\/.*/
deploy:
jobs:
- build:
filters:
tags:
only: /^.*/
branches:
ignore: /.*/
- e2e:
filters:
tags:
only: /^.*/
branches:
ignore: /.*/
- deploy:
requires:
- build
- e2e
filters:
tags:
only: /^.*/
branches:
ignore: /.*/

172
package-lock.json generated

@ -1104,6 +1104,12 @@
"integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==",
"dev": true
},
"buffer-equal-constant-time": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
"integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=",
"dev": true
},
"buffer-fill": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz",
@ -2090,6 +2096,15 @@
"safer-buffer": "^2.1.0"
}
},
"ecdsa-sig-formatter": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
"dev": true,
"requires": {
"safe-buffer": "^5.0.1"
}
},
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@ -3166,7 +3181,8 @@
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"aproba": {
"version": "1.2.0",
@ -3187,12 +3203,14 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -3207,17 +3225,20 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"core-util-is": {
"version": "1.0.2",
@ -3334,7 +3355,8 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"ini": {
"version": "1.3.5",
@ -3346,6 +3368,7 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@ -3360,6 +3383,7 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@ -3367,12 +3391,14 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@ -3391,6 +3417,7 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
@ -3478,7 +3505,8 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"object-assign": {
"version": "4.1.1",
@ -3490,6 +3518,7 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"wrappy": "1"
}
@ -3575,7 +3604,8 @@
"safe-buffer": {
"version": "5.1.2",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"safer-buffer": {
"version": "2.1.2",
@ -3611,6 +3641,7 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@ -3630,6 +3661,7 @@
"version": "3.0.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@ -3673,12 +3705,14 @@
"wrappy": {
"version": "1.0.2",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"yallist": {
"version": "3.0.3",
"bundled": true,
"dev": true
"dev": true,
"optional": true
}
}
},
@ -4756,6 +4790,32 @@
"graceful-fs": "^4.1.6"
}
},
"jsonwebtoken": {
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
"integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
"dev": true,
"requires": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"ms": "^2.1.1",
"semver": "^5.6.0"
},
"dependencies": {
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
}
}
},
"jsprim": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
@ -4796,6 +4856,27 @@
"integrity": "sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==",
"dev": true
},
"jwa": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
"integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
"dev": true,
"requires": {
"buffer-equal-constant-time": "1.0.1",
"ecdsa-sig-formatter": "1.0.11",
"safe-buffer": "^5.0.1"
}
},
"jws": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
"dev": true,
"requires": {
"jwa": "^1.4.1",
"safe-buffer": "^5.0.1"
}
},
"karma": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/karma/-/karma-4.2.0.tgz",
@ -5088,7 +5169,7 @@
}
},
"lanthan": {
"version": "git+https://github.com/ueokande/lanthan.git#fb7f641846369de5bac7762f19186d23248f0d53",
"version": "git+https://github.com/ueokande/lanthan.git#d7f92eb4c1c6eee3f747b4a76bdf39062b4cb58f",
"from": "git+https://github.com/ueokande/lanthan.git#master",
"dev": true,
"requires": {
@ -5300,6 +5381,48 @@
"integrity": "sha512-DHb1ub+rMjjrxqlB3H56/6MXtm1lSksDp2rA2cNWjG8mlDUYFhUj3Di2Zn5IwSU87xLv8tNIQ7sSwE/YOX/D/Q==",
"dev": true
},
"lodash.includes": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
"integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=",
"dev": true
},
"lodash.isboolean": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
"integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=",
"dev": true
},
"lodash.isinteger": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
"integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=",
"dev": true
},
"lodash.isnumber": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
"integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=",
"dev": true
},
"lodash.isplainobject": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
"integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=",
"dev": true
},
"lodash.isstring": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
"integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=",
"dev": true
},
"lodash.once": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
"integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=",
"dev": true
},
"lodash.unescape": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz",
@ -7662,14 +7785,6 @@
"dev": true,
"requires": {
"lodash": "^4.17.11"
},
"dependencies": {
"lodash": {
"version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
"dev": true
}
}
},
"request-promise-native": {
@ -8988,12 +9103,21 @@
"dev": true
},
"tough-cookie": {
"version": "2.3.4",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz",
"integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==",
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
"integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
"dev": true,
"requires": {
"punycode": "^1.4.1"
"psl": "^1.1.28",
"punycode": "^2.1.1"
},
"dependencies": {
"punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
"dev": true
}
}
},
"trim-newlines": {

@ -36,6 +36,7 @@
"eslint": "^6.2.2",
"eslint-plugin-react": "^7.14.3",
"html-webpack-plugin": "^3.2.0",
"jsonwebtoken": "^8.5.1",
"jszip": "^3.2.2",
"karma": "^4.2.0",
"karma-firefox-launcher": "^1.2.0",
@ -55,6 +56,7 @@
"redux": "^4.0.4",
"redux-promise": "^0.6.0",
"reflect-metadata": "^0.1.13",
"request-promise-native": "^1.0.7",
"sass-loader": "^7.3.1",
"sinon": "^7.4.1",
"sinon-chrome": "^3.0.1",

@ -0,0 +1,91 @@
#!/usr/bin/env node
const uuid = require('uuid');
const fs = require('fs');
const jwt = require('jsonwebtoken');
const request = require('request-promise-native');
class AMOClient {
constructor(issuer, secret) {
this.issuer = issuer;
this.secret = secret;
}
async getProfile() {
let token = this._getJwtToken();
let response = await request({
url: 'https://addons.mozilla.org/api/v4/accounts/profile/',
method: 'GET',
headers: {
Authorization: 'JWT ' + token,
}
});
return response;
};
async uploadVersion(guid, version, xpiPath) {
let token = this._getJwtToken();
const formData = {
upload: fs.createReadStream(xpiPath),
};
let url = `https://addons.mozilla.org/api/v4/addons/${encodeURIComponent(guid)}/versions/${encodeURIComponent(version)}/`
let response = await request({
url,
formData,
method: 'PUT',
headers: {
Authorization: 'JWT ' + token,
}
});
return response;
}
_getJwtToken() {
// See https://addons-server.readthedocs.io/en/latest/topics/api/auth.html
const issuedAt = Math.floor(Date.now() / 1000);
const payload = {
iss: this.issuer,
jti: uuid.v4(),
iat: issuedAt,
exp: issuedAt + 60,
};
return jwt.sign(payload, this.secret, { algorithm: 'HS256' });
}
}
const run = async() => {
let args = process.argv;
if (args.length != 5) {
console.error(`USAGE: ${args[1]} GUID VERSION XPI_PATH`)
console.error('')
console.error('Environment variables')
console.error(' JWT_ISSUER: JWT issuer generated by AMO')
console.error(' JWT_SECRET: JWT secret token generated by AMO')
process.exit(2);
}
let guid = args[2];
let version = args[3];
let xpiPath = args[4]
let jwtIssuer = process.env['JWT_ISSUER'];
let jwtSecret = process.env['JWT_SECRET'];
if (typeof jwtIssuer === 'undefined' || jwtIssuer.length === 0) {
console.error('JWT_ISSUER not set');
process.exit(2);
}
if (typeof jwtSecret === 'undefined' || jwtSecret.length === 0) {
console.error('JWT_SECRET not set');
process.exit(2);
}
let amo = new AMOClient(jwtIssuer, jwtSecret);
console.log(`Uploading ${xpiPath} to ${guid}/${version}`);
let response = await amo.uploadVersion(guid, version, xpiPath);
console.log(response);
};
run().catch((err) => {
console.error(err.error || err.message);
process.exit(1);
});