<commit_before>const debug = require('debug')('taskcluster-github:github-auth');
const Github = require('@octokit/rest');
const Promise = require('bluebird');
const jwt = require('jsonwebtoken');

module.exports = async ({cfg}) => {
  let github = new Github({
    promise: Promise,
  });

  let setupToken = _ => {
    let inteToken = jwt.sign(
      {iss: cfg.github.credentials.integrationId},
      cfg.github.credentials.privatePEM,
      {algorithm: 'RS256', expiresIn: '1m'},
    );
    try {
      github.authenticate({type: 'app', token: inteToken});
    } catch (e) {
      debug('Authentication as app failed!');
      throw e;
    }
    return github;
  };

  // This object insures that the authentication is delayed until we need it.
  // Also, the authentication happens not just once in the beginning, but for each request.
  return {
    getIntegrationGithub: async _ => {
      setupToken();
      return github;
    },<commit_msg>Add exponential backoff retries for eventual consistency from github<commit_after>const debug = require('debug')('taskcluster-github:github-auth');
const Promise = require('bluebird');
const jwt = require('jsonwebtoken');

const retryPlugin = (octokit, options) => {

  const retries = 7;
  const baseBackoff = 100;
  const sleep = timeout => new Promise(resolve => setTimeout(resolve, timeout));

  octokit.hook.wrap('request', async (request, options) => {
    let response;
    for (let attempt = 0; attempt < retries; attempt++) {
      try {
        response = await request(options);
        break;
      } catch (err) {
        if (err.name !== 'HttpError' || err.status !== 404) {
          throw err;
        }
        debug(`404 getting retried for eventual consistency. attempt: ${attempt}`);
        await sleep(baseBackoff * Math.pow(2, attempt));
      }
    }
    return response;
  });
};
const Github = require('@octokit/rest').plugin([retryPlugin]);

module.exports = async ({cfg}) => {
  let github = new Github({
    promise: Promise,
  });

  let setupToken = _ => {
    let inteToken = jwt.sign(
      {iss: cfg.github.credentials.integrationId},
      cfg.github.credentials.privatePEM,
      {algorithm: 'RS256', expiresIn: '1m'},
    );
    try {
      github.authenticate({type: 'app', token: inteToken});
    } catch (e) {
      debug('Authentication as app failed!');
      throw e;
    }
    return github;
  };

  // This object insures that the authentication is delayed until we need it.
  // Also, the authentication happens not just once in the beginning, but for each request.
  return {
    getIntegrationGithub: async _ => {
      setupToken();
      return github;
    },
{'fraction_non_alphanumeric': 0.13544018058690746, 'fraction_numerical': 0.007524454477050414, 'mean_word_length': 3.0533536585365852, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1503530', 'n_tokens_mistral': 807, 'n_tokens_neox': 773, 'n_words': 226}