diff options
| author | Shin'ya Ueoka <ueokande@i-beam.org> | 2019-09-05 03:30:41 +0000 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-09-05 03:30:41 +0000 | 
| commit | 428805e66f993884643136dc2d8267c53bd81588 (patch) | |
| tree | 630deab9c7db1ffd00ea205fa7f1f420da0de7cb /script | |
| parent | 763b24fe2114e10e8d040b4fe5b9fce22781de32 (diff) | |
| parent | b4bda1447abdddf35e498d5d792e30ec23034354 (diff) | |
Merge pull request #640 from ueokande/auto-deploy
Deploy an addon automatically
Diffstat (limited to 'script')
| -rwxr-xr-x | script/deploy | 91 | 
1 files changed, 91 insertions, 0 deletions
| diff --git a/script/deploy b/script/deploy new file mode 100755 index 0000000..3cc27b8 --- /dev/null +++ b/script/deploy @@ -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); +}); | 
