diff --git a/engine/src/flutter/.github/workflows/scorecards-analysis.yml b/engine/src/flutter/.github/workflows/scorecards-analysis.yml index e948472a1d7..8163b73e380 100644 --- a/engine/src/flutter/.github/workflows/scorecards-analysis.yml +++ b/engine/src/flutter/.github/workflows/scorecards-analysis.yml @@ -4,6 +4,9 @@ on: branch_protection_rule: push: branches: [ main ] + pull_request: + branches: + - main # Declare default permissions as read only. permissions: read-all @@ -21,12 +24,20 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 # v2.4.0 + uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 with: persist-credentials: false + - name: setup python + uses: actions/setup-python@0ebf233433c08fb9061af664d501c3f3ff0e9e20 + with: + python-version: '3.7.7' # install the python version needed + + - name: execute py script + run: python ci/deps_parser.py + - name: "Run analysis" - uses: ossf/scorecard-action@c8416b0b2bf627c349ca92fc8e3de51a64b005cf # v1.0.2 + uses: ossf/scorecard-action@c8416b0b2bf627c349ca92fc8e3de51a64b005cf with: results_file: results.sarif results_format: sarif @@ -41,7 +52,7 @@ jobs: # Upload the results as artifacts (optional). - name: "Upload artifact" - uses: actions/upload-artifact@82c141cc518b40d92cc801eee768e7aafc9c2fa2 # v2.3.1 + uses: actions/upload-artifact@82c141cc518b40d92cc801eee768e7aafc9c2fa2 with: name: SARIF file path: results.sarif @@ -49,6 +60,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@5f532563584d71fdef14ee64d17bafb34f751ce5 # v1.0.26 + uses: github/codeql-action/upload-sarif@5f532563584d71fdef14ee64d17bafb34f751ce5 with: sarif_file: results.sarif diff --git a/engine/src/flutter/ci/deps_parser.py b/engine/src/flutter/ci/deps_parser.py new file mode 100644 index 00000000000..b4e81045cde --- /dev/null +++ b/engine/src/flutter/ci/deps_parser.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python3 +# +# Copyright 2013 The Flutter Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Usage: deps_parser.py --deps --output +# +# This script parses the DEPS file, extracts the fully qualified dependencies +# and writes the to a file. This file will be later used to validate the dependencies +# are pinned to a hash. + +import argparse +import os +import sys + +SCRIPT_DIR = os.path.dirname(sys.argv[0]) +CHECKOUT_ROOT = os.path.realpath(os.path.join(SCRIPT_DIR, '..')) + + +# Used in parsing the DEPS file. +class VarImpl(object): + _env_vars = { + "host_cpu": "x64", + "host_os": "linux", + } + + def __init__(self, local_scope): + self._local_scope = local_scope + + def Lookup(self, var_name): + """Implements the Var syntax.""" + if var_name in self._local_scope.get("vars", {}): + return self._local_scope["vars"][var_name] + # Inject default values for env variables + if var_name in self._env_vars: + return self._env_vars[var_name] + raise Exception("Var is not defined: %s" % var_name) + + +def ParseDepsFile(deps_file): + local_scope = {} + var = VarImpl(local_scope) + global_scope = { + 'Var': var.Lookup, + 'deps_os': {}, + } + # Read the content. + with open(deps_file, 'r') as fp: + deps_content = fp.read() + + # Eval the content. + exec (deps_content, global_scope, local_scope) + + # Extract the deps and filter. + deps = local_scope.get('deps', {}) + filtered_deps = [] + for k, v in deps.items(): + # We currently do not support packages or cipd which are represented + # as dictionaries. + if isinstance(v, str): + filtered_deps.append(v) + + return filtered_deps + + +def WriteManifest(deps, manifest_file): + print('\n'.join(sorted(deps))) + with open(manifest_file, 'w') as manifest: + manifest.write('\n'.join(sorted(deps))) + + +def ParseArgs(args): + args = args[1:] + parser = argparse.ArgumentParser( + description='A script to flatten a gclient DEPS file.') + + parser.add_argument( + '--deps', + '-d', + type=str, + help='Input DEPS file.', + default=os.path.join(CHECKOUT_ROOT, 'DEPS')) + parser.add_argument( + '--output', + '-o', + type=str, + help='Output flattened deps file.', + default=os.path.join(CHECKOUT_ROOT, 'deps_flatten.txt')) + + return parser.parse_args(args) + + +def Main(argv): + args = ParseArgs(argv) + deps = ParseDepsFile(args.deps) + WriteManifest(deps, args.output) + return 0 + + +if __name__ == '__main__': + sys.exit(Main(sys.argv))