diff --git a/README.rst b/README.rst index df31e28..8e00d49 100644 --- a/README.rst +++ b/README.rst @@ -43,9 +43,9 @@ CLI Help output:: [--watched] [--followers] [--following] [--all] [--issues] [--issue-comments] [--issue-events] [--pulls] [--pull-comments] [--pull-commits] [--pull-details] - [--labels] [--hooks] [--milestones] [--repositories] - [--bare] [--no-prune] [--lfs] [--wikis] [--gists] - [--starred-gists] [--skip-archived] [--skip-existing] + [--labels] [--hooks] [--milestones] [--security-advisories] + [--repositories] [--bare] [--no-prune] [--lfs] [--wikis] + [--gists] [--starred-gists] [--skip-archived] [--skip-existing] [-L [LANGUAGES ...]] [-N NAME_REGEX] [-H GITHUB_HOST] [-O] [-R REPOSITORY] [-P] [-F] [--prefer-ssh] [-v] [--keychain-name OSX_KEYCHAIN_ITEM_NAME] @@ -101,6 +101,8 @@ CLI Help output:: --hooks include hooks in backup (works only when authenticated) --milestones include milestones in backup + --security-advisories + include security advisories in backup --repositories include repository clone in backup --bare clone bare repositories --no-prune disable prune option for git fetch @@ -401,7 +403,7 @@ Quietly and incrementally backup useful Github user data (public and private rep export FINE_ACCESS_TOKEN=SOME-GITHUB-TOKEN GH_USER=YOUR-GITHUB-USER - github-backup -f $FINE_ACCESS_TOKEN --prefer-ssh -o ~/github-backup/ -l error -P -i --all-starred --starred --watched --followers --following --issues --issue-comments --issue-events --pulls --pull-comments --pull-commits --labels --milestones --repositories --wikis --releases --assets --attachments --pull-details --gists --starred-gists $GH_USER + github-backup -f $FINE_ACCESS_TOKEN --prefer-ssh -o ~/github-backup/ -l error -P -i --all-starred --starred --watched --followers --following --issues --issue-comments --issue-events --pulls --pull-comments --pull-commits --labels --milestones --security-advisories --repositories --wikis --releases --assets --attachments --pull-details --gists --starred-gists $GH_USER Debug an error/block or incomplete backup into a temporary directory. Omit "incremental" to fill a previous incomplete backup. :: diff --git a/github_backup/github_backup.py b/github_backup/github_backup.py index 12b354b..8a60f66 100644 --- a/github_backup/github_backup.py +++ b/github_backup/github_backup.py @@ -310,6 +310,12 @@ def parse_args(args=None): dest="include_milestones", help="include milestones in backup", ) + parser.add_argument( + "--security-advisories", + action="store_true", + dest="include_security_advisories", + help="include security advisories in backup", + ) parser.add_argument( "--repositories", action="store_true", @@ -1718,6 +1724,9 @@ def backup_repositories(args, output_directory, repositories): if args.include_milestones or args.include_everything: backup_milestones(args, repo_cwd, repository, repos_template) + if args.include_security_advisories or args.include_everything: + backup_security_advisories(args, repo_cwd, repository, repos_template) + if args.include_labels or args.include_everything: backup_labels(args, repo_cwd, repository, repos_template) @@ -1934,6 +1943,41 @@ def backup_milestones(args, repo_cwd, repository, repos_template): ) +def backup_security_advisories(args, repo_cwd, repository, repos_template): + advisory_cwd = os.path.join(repo_cwd, "security-advisories") + if args.skip_existing and os.path.isdir(advisory_cwd): + return + + logger.info("Retrieving {0} security advisories".format(repository["full_name"])) + mkdir_p(repo_cwd, advisory_cwd) + + template = "{0}/{1}/security-advisories".format(repos_template, repository["full_name"]) + + _advisories = retrieve_data(args, template) + + advisories = {} + for advisory in _advisories: + advisories[advisory["ghsa_id"]] = advisory + + written_count = 0 + for ghsa_id, advisory in list(advisories.items()): + advisory_file = "{0}/{1}.json".format(advisory_cwd, ghsa_id) + if json_dump_if_changed(advisory, advisory_file): + written_count += 1 + + total = len(advisories) + if written_count == total: + logger.info("Saved {0} security advisories to disk".format(total)) + elif written_count == 0: + logger.info("{0} security advisories unchanged, skipped write".format(total)) + else: + logger.info( + "Saved {0} of {1} security advisories to disk ({2} unchanged)".format( + written_count, total, total - written_count + ) + ) + + def backup_labels(args, repo_cwd, repository, repos_template): label_cwd = os.path.join(repo_cwd, "labels") output_file = "{0}/labels.json".format(label_cwd) diff --git a/tests/test_all_starred.py b/tests/test_all_starred.py index 0fab048..297d148 100644 --- a/tests/test_all_starred.py +++ b/tests/test_all_starred.py @@ -37,6 +37,7 @@ def _create_mock_args(self, **overrides): args.include_labels = False args.include_hooks = False args.include_milestones = False + args.include_security_advisories = False args.include_releases = False args.include_assets = False args.include_attachments = False