Compare commits

...

6 Commits

Author SHA1 Message Date
GitHub Action
c63fb37d30 Release version 0.61.0 2026-01-12 16:30:28 +00:00
Jose Diaz-Gonzalez
94b08d06c9 Merge pull request #476 from lukasbestle/patch-1
docs: Add missing `--retries` argument to README
2026-01-12 11:29:56 -05:00
Jose Diaz-Gonzalez
54a9872e47 Merge pull request #475 from lukasbestle/feat/security-advisories
feat: Backup of repository security advisories
2026-01-11 14:26:39 -05:00
Lukas Bestle
b3d35f9d9f docs: Add missing --retries argument to README 2026-01-10 15:44:37 +01:00
Lukas Bestle
a175ac3ed9 test: Adapt tests to new argument 2026-01-10 11:12:42 +01:00
Lukas Bestle
9a6f0b4c21 feat: Backup of repository security advisories 2026-01-09 21:04:21 +01:00
5 changed files with 61 additions and 7 deletions

View File

@@ -1,9 +1,16 @@
Changelog Changelog
========= =========
0.60.0 (2025-12-24) 0.61.0 (2026-01-12)
------------------- -------------------
------------------------ ------------------------
- Docs: Add missing `--retries` argument to README. [Lukas Bestle]
- Test: Adapt tests to new argument. [Lukas Bestle]
- Feat: Backup of repository security advisories. [Lukas Bestle]
0.60.0 (2025-12-24)
-------------------
- Rm max_retries.py. [michaelmartinez] - Rm max_retries.py. [michaelmartinez]
- Readme. [michaelmartinez] - Readme. [michaelmartinez]
- Don't use a global variable, pass the args instead. [michaelmartinez] - Don't use a global variable, pass the args instead. [michaelmartinez]

View File

@@ -43,9 +43,9 @@ CLI Help output::
[--watched] [--followers] [--following] [--all] [--watched] [--followers] [--following] [--all]
[--issues] [--issue-comments] [--issue-events] [--pulls] [--issues] [--issue-comments] [--issue-events] [--pulls]
[--pull-comments] [--pull-commits] [--pull-details] [--pull-comments] [--pull-commits] [--pull-details]
[--labels] [--hooks] [--milestones] [--repositories] [--labels] [--hooks] [--milestones] [--security-advisories]
[--bare] [--no-prune] [--lfs] [--wikis] [--gists] [--repositories] [--bare] [--no-prune] [--lfs] [--wikis]
[--starred-gists] [--skip-archived] [--skip-existing] [--gists] [--starred-gists] [--skip-archived] [--skip-existing]
[-L [LANGUAGES ...]] [-N NAME_REGEX] [-H GITHUB_HOST] [-L [LANGUAGES ...]] [-N NAME_REGEX] [-H GITHUB_HOST]
[-O] [-R REPOSITORY] [-P] [-F] [--prefer-ssh] [-v] [-O] [-R REPOSITORY] [-P] [-F] [--prefer-ssh] [-v]
[--keychain-name OSX_KEYCHAIN_ITEM_NAME] [--keychain-name OSX_KEYCHAIN_ITEM_NAME]
@@ -55,7 +55,7 @@ CLI Help output::
[--skip-assets-on [SKIP_ASSETS_ON ...]] [--attachments] [--skip-assets-on [SKIP_ASSETS_ON ...]] [--attachments]
[--throttle-limit THROTTLE_LIMIT] [--throttle-limit THROTTLE_LIMIT]
[--throttle-pause THROTTLE_PAUSE] [--throttle-pause THROTTLE_PAUSE]
[--exclude [EXCLUDE ...]] [--exclude [EXCLUDE ...]] [--retries MAX_RETRIES]
USER USER
Backup a github account Backup a github account
@@ -101,6 +101,8 @@ CLI Help output::
--hooks include hooks in backup (works only when --hooks include hooks in backup (works only when
authenticated) authenticated)
--milestones include milestones in backup --milestones include milestones in backup
--security-advisories
include security advisories in backup
--repositories include repository clone in backup --repositories include repository clone in backup
--bare clone bare repositories --bare clone bare repositories
--no-prune disable prune option for git fetch --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 export FINE_ACCESS_TOKEN=SOME-GITHUB-TOKEN
GH_USER=YOUR-GITHUB-USER 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. :: Debug an error/block or incomplete backup into a temporary directory. Omit "incremental" to fill a previous incomplete backup. ::

View File

@@ -1 +1 @@
__version__ = "0.60.0" __version__ = "0.61.0"

View File

@@ -310,6 +310,12 @@ def parse_args(args=None):
dest="include_milestones", dest="include_milestones",
help="include milestones in backup", 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( parser.add_argument(
"--repositories", "--repositories",
action="store_true", action="store_true",
@@ -1718,6 +1724,9 @@ def backup_repositories(args, output_directory, repositories):
if args.include_milestones or args.include_everything: if args.include_milestones or args.include_everything:
backup_milestones(args, repo_cwd, repository, repos_template) 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: if args.include_labels or args.include_everything:
backup_labels(args, repo_cwd, repository, repos_template) 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): def backup_labels(args, repo_cwd, repository, repos_template):
label_cwd = os.path.join(repo_cwd, "labels") label_cwd = os.path.join(repo_cwd, "labels")
output_file = "{0}/labels.json".format(label_cwd) output_file = "{0}/labels.json".format(label_cwd)

View File

@@ -37,6 +37,7 @@ class TestAllStarredCloning:
args.include_labels = False args.include_labels = False
args.include_hooks = False args.include_hooks = False
args.include_milestones = False args.include_milestones = False
args.include_security_advisories = False
args.include_releases = False args.include_releases = False
args.include_assets = False args.include_assets = False
args.include_attachments = False args.include_attachments = False