backstage

Форк
0
/
run-fossa.js 
141 строка · 3.9 Кб
1
#!/usr/bin/env node
2
/*
3
 * Copyright 2020 The Backstage Authors
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at
8
 *
9
 *     http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17

18
// This script generates an appropriate fossa config, and wraps the running
19
// of `fossa analyze` in a retry loop as it frequently fails with a 502 error
20

21
const { resolve: resolvePath, join: joinPath, basename } = require('path');
22
const { promises: fs } = require('fs');
23
const { execFile: execFileCb } = require('child_process');
24
const { promisify } = require('util');
25

26
const execFile = promisify(execFileCb);
27

28
const FOSSA_YAML_HEAD = `
29
version: 2
30
cli:
31
  server: https://app.fossa.com
32
  fetcher: custom
33
  project: backstage
34
analyze:
35
  modules:`;
36

37
const IGNORED_DIRS = ['node_modules', 'dist', 'bin', '.git'];
38

39
// Finds all directories containing package.json files that we're interested in analyzing
40
async function findPackageJsonDirs(dir, depth = 0) {
41
  if (depth > 2) {
42
    return []; // Skipping packages that are deeper than 2 dirs in
43
  }
44
  const files = await fs.readdir(dir);
45
  const paths = await Promise.all(
46
    files
47
      .filter(file => !IGNORED_DIRS.includes(file))
48
      .map(async file => {
49
        const path = joinPath(dir, file);
50

51
        if ((await fs.stat(path)).isDirectory()) {
52
          return findPackageJsonDirs(path, depth + 1);
53
        } else if (file === 'package.json') {
54
          return dir;
55
        }
56
        return [];
57
      }),
58
  );
59
  return paths.flat();
60
}
61

62
// A replacement for `fossa init`, as that generates a bad config for this repo
63
async function generateConfig(paths) {
64
  let content = FOSSA_YAML_HEAD;
65

66
  for (const path of paths) {
67
    content += `
68
  - name: ${basename(path)}
69
    type: npm
70
    path: ${path}
71
    target: ${path}
72
    options:
73
      strategy: yarn-list
74
`;
75
  }
76

77
  return content;
78
}
79

80
// Runs `fossa analyze`, with 502 errors being retried up to 3 times
81
async function runAnalyze(githubRef) {
82
  for (let attempt = 1; attempt <= 3; attempt++) {
83
    console.error(`Running fossa analyze, attempt ${attempt}`);
84
    try {
85
      const { stdout, stderr } = await execFile(
86
        'fossa',
87
        ['analyze', '--branch', githubRef],
88
        { shell: true },
89
      );
90
      console.error(stderr);
91
      console.log(stdout);
92

93
      return; // Analyze was successful, we're done
94
    } catch (error) {
95
      if (!error.code) {
96
        throw error;
97
      }
98
      if (error.stderr) {
99
        process.stderr.write(error.stderr);
100
      }
101
      if (error.stdout) {
102
        process.stdout.write(error.stdout);
103
      }
104
      if (error.stderr && error.stderr.includes('502 Bad Gateway')) {
105
        console.error('Encountered 502 during fossa analysis upload, retrying');
106
        continue;
107
      }
108
      throw new Error(`Fossa analyze failed with code ${error.code}`);
109
    }
110
  }
111

112
  console.error('Maximum number of retries reached, skipping fossa analysis');
113
}
114

115
async function main() {
116
  const githubRef = process.env.GITHUB_REF;
117
  if (!githubRef) {
118
    throw new Error('GITHUB_REF is not set');
119
  }
120
  // This is picked up by the fossa CLI and should be set
121
  if (!process.env.FOSSA_API_KEY) {
122
    throw new Error('FOSSA_API_KEY is not set');
123
  }
124

125
  process.cwd(resolvePath(__dirname, '..'));
126

127
  const packageJsonPaths = await findPackageJsonDirs('.');
128

129
  const configContents = await generateConfig(packageJsonPaths);
130

131
  await fs.writeFile('.fossa.yml', configContents, 'utf8');
132

133
  console.error(`Generated fossa config:\n${configContents}`);
134

135
  await runAnalyze(githubRef);
136
}
137

138
main().catch(error => {
139
  console.error(error.stack);
140
  process.exit(1);
141
});
142

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.