Compare commits

...

321 Commits

Author SHA1 Message Date
GitHub Action
aaf45022cc Release version 0.44.1 2023-12-09 05:53:43 +00:00
Jose Diaz-Gonzalez
7cdf428e3a fix: use a deploy key to push tags so releases get auto-created 2023-12-09 00:52:00 -05:00
Jose Diaz-Gonzalez
cfb1f1368b Merge pull request #228 from josegonzalez/dependabot/pip/certifi-2023.7.22
chore(deps): bump certifi from 2023.5.7 to 2023.7.22
2023-12-09 00:45:27 -05:00
Jose Diaz-Gonzalez
4700a26d90 tests: run lint on pull requests 2023-12-09 00:45:20 -05:00
dependabot[bot]
f53f7d9b71 chore(deps): bump certifi from 2023.5.7 to 2023.7.22
Bumps [certifi](https://github.com/certifi/python-certifi) from 2023.5.7 to 2023.7.22.
- [Commits](https://github.com/certifi/python-certifi/compare/2023.05.07...2023.07.22)

---
updated-dependencies:
- dependency-name: certifi
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-09 05:43:45 +00:00
Jose Diaz-Gonzalez
3b6aa060ba Merge pull request #227 from josegonzalez/dependabot/pip/urllib3-2.0.7
chore(deps): bump urllib3 from 2.0.2 to 2.0.7
2023-12-09 00:42:54 -05:00
Jose Diaz-Gonzalez
76ff7f3b0d chore: remove circleci as tests now run in github actions 2023-12-09 00:42:09 -05:00
Jose Diaz-Gonzalez
2615cab114 tests: install correct dependencies and rename job 2023-12-09 00:40:58 -05:00
Jose Diaz-Gonzalez
fda71b0467 tests: add lint github action workflow 2023-12-09 00:39:40 -05:00
Jose Diaz-Gonzalez
a9f82faa1c feat: install autopep8 2023-12-09 00:39:40 -05:00
Jose Diaz-Gonzalez
f17bf19776 Merge pull request #226 from josegonzalez/dependabot/pip/certifi-2023.7.22
chore(deps): bump certifi from 2023.5.7 to 2023.7.22
2023-12-09 00:31:43 -05:00
dependabot[bot]
54c81de3d7 chore(deps): bump urllib3 from 2.0.2 to 2.0.7
Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.0.2 to 2.0.7.
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/2.0.2...2.0.7)

---
updated-dependencies:
- dependency-name: urllib3
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-09 05:31:30 +00:00
dependabot[bot]
f2b4f566a1 chore(deps): bump certifi from 2023.5.7 to 2023.7.22
Bumps [certifi](https://github.com/certifi/python-certifi) from 2023.5.7 to 2023.7.22.
- [Commits](https://github.com/certifi/python-certifi/compare/2023.05.07...2023.07.22)

---
updated-dependencies:
- dependency-name: certifi
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-09 05:31:23 +00:00
Jose Diaz-Gonzalez
2724f02b0a chore: reformat file and update flake8 2023-12-09 00:30:44 -05:00
GitHub Action
e0bf80a6aa Release version 0.44.0 2023-12-09 05:26:00 +00:00
Jose Diaz-Gonzalez
b60034a9d7 fix: do not use raw property in readme
This is disabled on pypi.
2023-12-09 00:25:28 -05:00
Jose Diaz-Gonzalez
878713a4e0 fix: validate release before committing and uploading it 2023-12-09 00:22:36 -05:00
Jose Diaz-Gonzalez
3b0c08cdc1 fix: correct lint issues and show errors on lint 2023-12-09 00:08:19 -05:00
Jose Diaz-Gonzalez
b52d9bfdc8 Merge pull request #215 from josegonzalez/dependabot/pip/certifi-2023.7.22
Bump certifi from 2023.5.7 to 2023.7.22
2023-12-09 00:04:48 -05:00
Jose Diaz-Gonzalez
336b8b746f Merge pull request #223 from Ondkloss/feature/auto-release
Added automatic release workflow, for use with GitHub Actions
2023-12-09 00:04:38 -05:00
Jose Diaz-Gonzalez
4e7d6f7497 Merge pull request #222 from pl4nty/patch-1
feat: create Dockerfile
2023-12-09 00:00:20 -05:00
Jose Diaz-Gonzalez
7d07cbbe4f Merge pull request #224 from hozza/master
more detailed README docs
2023-12-08 23:59:55 -05:00
Jose Diaz-Gonzalez
b80af2a4ca Merge pull request #221 from josegonzalez/dependabot/pip/urllib3-2.0.7
Bump urllib3 from 2.0.2 to 2.0.7
2023-12-08 23:59:20 -05:00
hozza
5dd0744ce0 fix rst html 2023-11-07 16:12:26 +00:00
hozza
81876a2bb3 add contributor section 2023-11-07 16:08:35 +00:00
hozza
a2b13c8109 fix readme wording and format 2023-11-07 16:08:00 +00:00
hozza
f63be3be24 fixed readme working and layout 2023-11-07 15:46:03 +00:00
hozza
9cf85b087f fix readme formatting, spelling and layout 2023-11-07 15:28:39 +00:00
hozza
f449d8bbe3 added details usage and examples
including gotchas, errors and development instructions.
2023-11-07 14:56:43 +00:00
hozza
7d03e4c9bb added verbose install instructions 2023-11-07 14:53:58 +00:00
Halvor Holsten Strand
4406ba7f07 Checkout everything. 2023-10-29 20:37:20 +01:00
Halvor Holsten Strand
febf380c57 Updated to latest Ubuntu LTS while keeping setup-python to stay put on Python 3.8. 2023-10-28 20:19:18 +02:00
Halvor Holsten Strand
f9b627c1e4 Added automatic release workflow, for use with GitHub Actions. 2023-10-28 08:33:58 +02:00
Tom Plant
f998943171 feat: create Dockerfile 2023-10-28 16:30:31 +11:00
dependabot[bot]
2bf8898545 Bump urllib3 from 2.0.2 to 2.0.7
Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.0.2 to 2.0.7.
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/2.0.2...2.0.7)

---
updated-dependencies:
- dependency-name: urllib3
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-17 20:24:18 +00:00
Jose Diaz-Gonzalez
dbc1619106 Merge pull request #218 from Ondkloss/fix/win32logger
Suggested modification to fix win32 logging failure
2023-10-09 20:38:38 -04:00
Jose Diaz-Gonzalez
ec210166f7 Merge pull request #219 from Ondkloss/feature/quiet_flag
Add support for quiet flag
2023-10-09 20:34:30 -04:00
Halvor Holsten Strand
ea74aa5094 Merge branch 'master' into feature/quiet_flag. 2023-10-09 12:07:24 +02:00
Halvor Holsten Strand
7437e3abb1 Merge pull request, while keeping -q --quiet flag.
Most changes were already included, only adjusted with black formatting.
2023-10-09 12:01:32 +02:00
Halvor Holsten Strand
6f3be3d0e8 Suggested modification to fix win32 logging failure, due to local variable scope.
Logger does not appear to have any utility within "logging_subprocess".
2023-10-07 19:02:52 +02:00
Jose Diaz-Gonzalez
d7ba57075e Merge pull request #216 from Ondkloss/feature/fine_grained
Add support for fine-grained tokens (continued)
2023-10-07 00:04:17 -04:00
Halvor Holsten Strand
b277baa6ea Update github_backup.py 2023-10-02 09:14:40 +02:00
Halvor Holsten Strand
15de769d67 Simplified one if/elif scenario.
Extracted file reading of another if/elif scenario.
2023-10-01 22:22:15 +02:00
Halvor Holsten Strand
a9d35c0fd5 Ran black. 2023-09-29 14:40:16 +02:00
Halvor Holsten Strand
20f5fd7a86 Merge branch 'master' into feature/fine_grained
# Conflicts:
#	README.rst
#	github_backup/github_backup.py
2023-09-29 14:34:06 +02:00
Halvor Holsten Strand
f12b877509 Keep backwards compatability by going back to "--token" for classic.
Allow "file://" uri for "--token-fine".
2023-09-29 14:01:53 +02:00
dependabot[bot]
96e6f58159 Bump certifi from 2023.5.7 to 2023.7.22
Bumps [certifi](https://github.com/certifi/python-certifi) from 2023.5.7 to 2023.7.22.
- [Commits](https://github.com/certifi/python-certifi/compare/2023.05.07...2023.07.22)

---
updated-dependencies:
- dependency-name: certifi
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-25 23:20:45 +00:00
Jose Diaz-Gonzalez
d163cd66a4 Merge pull request #214 from ZhymabekRoman/master
fix: refactor logging
2023-06-27 15:21:16 -04:00
ZhymabekRoman
a8a583bed1 fix: minor cosmetic changes 2023-06-25 10:41:48 +06:00
ZhymabekRoman
68e718010f fix: add forgotten variable formatting 2023-06-25 10:39:16 +06:00
ZhymabekRoman
a06c3e9fd3 fix: refactor logging
Based on #195
2023-06-25 10:38:31 +06:00
Jose Diaz-Gonzalez
fe07d5ad09 Merge pull request #212 from ZhymabekRoman/dev-1
fix: minor typo fix
2023-06-23 13:04:17 -04:00
Zhymabek Roman
12799bb72c fix: minor typo fix 2023-06-23 21:27:52 +06:00
Jose Diaz-Gonzalez
f1cf4cd315 Release version 0.43.1 2023-05-29 18:45:57 -04:00
Jose Diaz-Gonzalez
f3340cd9eb chore: add release requirements 2023-05-29 18:45:49 -04:00
Jose Diaz-Gonzalez
0ebaffd102 Release version 0.43.0 2023-05-29 18:44:23 -04:00
Jose Diaz-Gonzalez
2730fc3e5a fix: do not update readme 2023-05-29 18:44:13 -04:00
Jose Diaz-Gonzalez
0b2330c2c4 fix: adjust for black 2023-05-29 18:43:29 -04:00
Jose Diaz-Gonzalez
82e35fb1cf feat: commit gitchangelog.rc to repo so anyone can generate a changelog 2023-05-29 18:43:23 -04:00
Jose Diaz-Gonzalez
e8f027469e fix: adjust for black 2023-05-29 18:37:02 -04:00
Jose Diaz-Gonzalez
37ef0222e1 fix: adjust for black 2023-05-29 18:36:06 -04:00
Jose Diaz-Gonzalez
96a73b3fe8 feat: add release tagging 2023-05-29 18:35:07 -04:00
Jose Diaz-Gonzalez
8b1bfd433c chore: formatting 2023-05-29 18:34:22 -04:00
Jose Diaz-Gonzalez
cca8a851ad chore: run black 2023-05-29 18:32:39 -04:00
josegonzalez
b5d749ec46 Merge pull request #199 from eht16/add_log_level_argument
Add --log-level command line argument
2023-05-29 18:29:41 -04:00
josegonzalez
00e5c019db Merge pull request #207 from kenbailey/kenbailey-patch-1
Check both updated_at and pushed_at properties
2023-05-29 18:29:29 -04:00
Robert Davey
61275c61b2 Update README.rst
Add flags and example for fine-grained tokens
2023-03-28 16:52:48 +01:00
froggleston
60cb484a19 Add support for fine-grained tokens 2023-03-22 14:53:07 +00:00
Ken Bailey
fbb977acf4 Check both updated_at and pushed_at properties
Check both updated_at and pushed_at dates to get the last_update to reduce data retrieved on incremental api calls using since.
2023-02-28 15:44:14 -07:00
Jose Diaz-Gonzalez
07e32b186c Release version 0.42.0 2022-11-28 00:25:13 -05:00
josegonzalez
dcc90b747a Merge pull request #204 from Assimila/exclude_repositories
Add option to exclude repositories
2022-11-28 00:23:20 -05:00
josegonzalez
f414fac108 Merge pull request #202 from TheOneric/pull_backup-regular-comments
Backup regular pull request comments as well
2022-11-28 00:23:08 -05:00
josegonzalez
38692bc836 Merge pull request #201 from TRAdEWORKS/fix-bug-request-url-error-forever-retry
Fix a bug forever retry when request url error
2022-11-28 00:22:54 -05:00
josegonzalez
81362e5596 Merge pull request #200 from TRAdEWORKS/no-prune-flag
Add --no-prune command line argument to disable prune option when doing git fetch
2022-11-28 00:22:40 -05:00
npounder
753a26d0d6 add option to exclude repositories 2022-11-25 12:35:24 +00:00
Oneric
b629a865f4 Backup regular pull request comments as well
Before, only review comments were backed up;
regular comments need to be fetched via issue API.

Fixes: https://github.com/josegonzalez/python-github-backup/issues/150
2022-07-12 18:38:11 +02:00
kornpisey
75ec773a6f fix bug forever retry when request url error 2022-05-30 13:50:23 +09:00
kornpisey
f8a16ee0f8 added --no-prune option to disable prune option when doing git fetch 2022-05-30 13:46:41 +09:00
Enrico Tröger
3d5eb359e2 Add --log-level command line argument
Support changing the log level to the desired value easily.
For example, this is useful to suppress progress messages but
keep logging warnings and errors.
2022-05-26 10:04:36 +02:00
Harrison Wright
125cfca05e Refactor logging and add support for quiet flag 2022-03-23 19:05:36 -05:00
Jose Diaz-Gonzalez
63441ebfbc Release version 0.41.0 2022-03-02 02:36:41 -05:00
Jose Diaz-Gonzalez
7ad324225e Merge pull request #191 from SkySoft-ATM/bug/lfs_mirror
git lfs clone does not respect --mirror
2022-03-02 02:34:17 -05:00
Louis Parisot
885e94a102 git lfs clone doe snot respect --mirror 2022-02-03 11:45:59 +01:00
Jose Diaz-Gonzalez
9e1800f56e Release version 0.40.2 2021-12-29 12:49:10 -05:00
Jose Diaz-Gonzalez
d057ee0d04 Merge pull request #186 from atinary-afoulon/patch-1
Fix lint issues raised by Flake8
2021-12-29 12:48:30 -05:00
atinary-afoulon
64562f2460 Fix lint issues raised by Flake8
According to job: 
[ https://app.circleci.com/pipelines/github/josegonzalez/python-github-backup/30/workflows/74eb93f2-2505-435d-b728-03b3cc04c14a/jobs/23 ]

Failed on the following checks:
./github_backup/github_backup.py:20:1: F811 redefinition of unused 'logging' from line 14
./github_backup/github_backup.py:45:1: E302 expected 2 blank lines, found 1
./github_backup/github_backup.py:136:20: E251 unexpected spaces around keyword / parameter equals
2021-12-13 14:33:21 +01:00
Jose Diaz-Gonzalez
f7f9ffd017 Release version 0.40.1 2021-09-22 12:29:08 -04:00
Jose Diaz-Gonzalez
048ef04e2a Merge pull request #180 from whwright/revert-to-fetch
Revert to fetch
2021-09-22 11:06:18 -04:00
Harrison Wright
b1acfed83a Revert to fetch 2021-07-14 10:53:14 -05:00
Jose Diaz-Gonzalez
18e78a4d66 Release version 0.40.0 2021-07-12 00:44:33 -04:00
Jose Diaz-Gonzalez
1ed5427043 Merge pull request #177 from jacekn/retry
Add retry on certain network errors
2021-07-12 00:43:19 -04:00
Jose Diaz-Gonzalez
c2e3665ed8 Merge pull request #178 from pew/patch-1
pull changes from remote
2021-07-12 00:43:10 -04:00
Jonas
0a30a92fe4 pull changes from remote
use `git pull` to pull actual files from the remote instead of using `fetch` for only the metadata
2021-07-06 06:21:06 +02:00
Jacek Nykis
cc52587f52 Add retry on certain network errors
This change includes certain network level errors in the retry logic.
It partially address #110 but I think more comprehensive fix would be useful.
2021-07-01 14:39:10 +01:00
Jose Diaz-Gonzalez
853b7c46a1 Release version 0.39.0 2021-03-18 23:16:04 -04:00
Jose Diaz-Gonzalez
e23d12d490 Merge pull request #173 from gallofeliz/make-compatible-python-call
Try to make compatible code with direct Python call ; reduce the hard link of the code with the cli
2021-03-18 22:51:01 -04:00
Jose Diaz-Gonzalez
f8e1151111 Merge pull request #174 from atorrescogollo/master
Fixed release_name with slash bug
2021-03-18 22:50:21 -04:00
Álvaro Torres Cogollo
664c2a765e Fixed release_name with slash bug 2021-03-03 11:36:44 +01:00
Gallo Feliz
fa7148d38f fix: fix missing INFO logs 2021-02-16 13:25:16 +01:00
Gallo Feliz
480ce3ce2a Try to make compatible code with direct Python call ; reduce the hard link of the code with the cli 2021-02-16 13:13:51 +01:00
Jose Diaz-Gonzalez
943e84e3d9 Release version 0.38.0 2021-02-13 03:55:02 -05:00
Jose Diaz-Gonzalez
0c924c3158 Merge pull request #172 from samanthaq/always-use-oauth-when-provided
fix: Always clone with OAuth token when provided
2021-02-13 03:53:26 -05:00
Samantha Baldwin
f62c4eaf8b fix: Always clone with OAuth token when provided
Github Enterprise servers with 'Anonymous Git read access' disabled
cause `git ls-remote` to fail (128) for a repo's `clone_url`. Using the
OAuth token when provided allows cloning private AND public repos when
Anonymous Git read access is disabled.
2021-02-12 00:46:06 -05:00
Jose Diaz-Gonzalez
a53d7f6849 Merge pull request #170 from Mindavi/bugfix/broken-url
Fix broken and incorrect link to github repository
2021-01-18 00:12:09 -05:00
Rick van Schijndel
4e571d0735 Change broken link to a fork to a working link to upstream 2021-01-03 23:08:58 +01:00
Jose Diaz-Gonzalez
5a71bc5e5a Release version 0.37.2 2021-01-01 21:31:06 -05:00
Jose Diaz-Gonzalez
794ccf3996 fix: use distutils.core on error 2021-01-01 21:30:54 -05:00
Jose Diaz-Gonzalez
977424c153 Release version 0.37.1 2021-01-01 21:28:25 -05:00
Jose Diaz-Gonzalez
613576dd25 fix: use twine for releases
The old method of releasing to pypi broke for whatever reason and switching to a supported toolchain is easier than debugging the old one.

Additionally:

- Update gitchangelog
- Fix license entry
- Set long description type
- Gitignore the temporary readme file
2021-01-01 21:28:03 -05:00
Jose Diaz-Gonzalez
638bf7a77e Release version 0.37.0 2021-01-01 21:23:49 -05:00
Jose Diaz-Gonzalez
725f2c3b8f Merge pull request #158 from albertyw/python3
Remove support for python 2
2021-01-01 21:22:30 -05:00
Jose Diaz-Gonzalez
41ece08152 Merge pull request #165 from garymoon/add-skip-archived
Add option to skip archived repositories
2021-01-01 21:22:15 -05:00
Gary Moon
3a5ef5158d Add ability to skip archived repositories 2020-10-30 15:39:32 -04:00
Albert Wang
cb1b0b6c6b Add support for python 3.7 and 3.8 in package classifiers 2020-08-28 23:45:30 -07:00
Albert Wang
d7f0747432 Remove support for python 2.7 in package classifiers 2020-08-28 23:45:30 -07:00
Albert Wang
d411e20580 Remove python 2 specific import logic 2020-08-28 23:45:30 -07:00
Albert Wang
d7b85264cd Remove python 2 specific logic 2020-08-28 23:45:30 -07:00
Jose Diaz-Gonzalez
031a984434 Release version 0.36.0 2020-08-29 02:37:48 -04:00
Jose Diaz-Gonzalez
9e16f39e3e Merge pull request #157 from albertyw/lint 2020-08-29 02:37:19 -04:00
Albert Wang
2de96390be Add flake8 instructions to readme 2020-08-28 23:13:24 -07:00
Albert Wang
78cff47a91 Fix regex string 2020-08-28 23:13:24 -07:00
Albert Wang
fa27988c1c Update boolean check 2020-08-28 23:13:23 -07:00
Albert Wang
bb2e2b8c6f Fix whitespace issues 2020-08-28 23:13:23 -07:00
Albert Wang
8fd0f2b64f Do not use bare excepts 2020-08-28 23:13:23 -07:00
Jose Diaz-Gonzalez
753a551961 Merge pull request #161 from albertyw/circleci-project-setup
Add circleci config
2020-08-29 01:48:49 -04:00
Albert Wang
607b6ca69b Add .circleci/config.yml 2020-08-28 02:33:51 -07:00
Jose Diaz-Gonzalez
ef71655b01 Merge pull request #160 from wbolster/patch-1
Include --private flag in example
2020-08-27 13:23:28 -04:00
wouter bolsterlee
d8bcbfa644 Include --private flag in example
By default, private repositories are not included. This is surprising.
It took me a while to figure this out, and making that clear in the
example can help others to be aware of that.
2020-08-27 17:01:56 +02:00
Jose Diaz-Gonzalez
751b0d6e82 Release version 0.35.0 2020-08-05 12:02:21 -04:00
Jose Diaz-Gonzalez
ea633ca2bb Merge pull request #156 from samanthaq/restore-optional-throttling
Make API request throttling optional
2020-08-05 12:01:56 -04:00
Samantha Baldwin
a2115ce3e5 Make API request throttling optional 2020-08-05 11:53:17 -04:00
Jose Diaz-Gonzalez
8a00bb1903 Release version 0.34.0 2020-07-24 13:31:03 -04:00
Jose Diaz-Gonzalez
e53f8d4724 Merge pull request #153 from 0x6d617474/gist_ssh
Add logic for transforming gist repository urls to ssh
2020-07-24 13:30:40 -04:00
Matt Fields
356f5f674b Add logic for transforming gist repository urls to ssh 2020-07-07 17:54:16 -04:00
Jose Diaz-Gonzalez
13128635cb Release version 0.33.1 2020-05-28 16:44:40 -04:00
Jose Diaz-Gonzalez
6e6842b025 Merge pull request #151 from garymoon/readme-update-0.33 2020-05-28 16:43:57 -04:00
Gary Moon
272177c395 Update the readme for new switches added in 0.33 2020-05-26 19:59:47 -04:00
Jose Diaz-Gonzalez
70f711ea68 Release version 0.33.0 2020-04-13 17:14:20 -04:00
Jose Diaz-Gonzalez
3fc9957aac Merge pull request #149 from eht16/simple_api_request_throttling
Add basic API request throttling
2020-04-13 17:13:58 -04:00
Enrico Tröger
78098aae23 Add basic API request throttling
A simple approach to throttle API requests and so keep within the rate
limits of the API. Can be enabled with "--throttle-limit" to specify
when throttling should start.
"--throttle-pause" defines the time to sleep between further API
requests.
2020-04-13 23:06:09 +02:00
Jose Diaz-Gonzalez
fb7cc5ed53 Release version 0.32.0 2020-04-13 17:02:59 -04:00
Jose Diaz-Gonzalez
c0679b9cc3 Merge pull request #148 from eht16/logging_with_timestamp
Add timestamp to log messages
2020-04-13 16:38:36 -04:00
Enrico Tröger
03b9d1b2d8 Add timestamp to log messages 2020-04-13 22:11:48 +02:00
Jose Diaz-Gonzalez
5025f69878 Merge pull request #147 from tomhoover/update-readme
Update README.rst to match 'github-backup -h'
2020-03-24 11:17:44 -04:00
Tom Hoover
a351cdc103 Update README.rst to match 'github-backup -h' 2020-03-22 08:48:50 -05:00
Jose Diaz-Gonzalez
85e4399408 Release version 0.31.0 2020-02-25 14:41:22 -05:00
Jose Diaz-Gonzalez
c8171b692a Merge pull request #146 from timm3/upstream-123
Authenticate as Github App
2020-02-25 14:39:27 -05:00
ethan
523c811cc6 #123 update: changed --as-app 'help' description 2020-02-25 13:13:20 -06:00
ethan
857ad0afab #123: Support Authenticating As Github Application 2020-02-25 12:35:24 -06:00
Jose Diaz-Gonzalez
3f65eadee1 Release version 0.30.0 2020-02-14 12:01:05 -05:00
Jose Diaz-Gonzalez
a8e8841b26 Release version 0.29.0 2020-02-14 12:00:07 -05:00
Jose Diaz-Gonzalez
8e542fd6b6 Merge pull request #145 from timm3/50-v0.28.0
#50 - refactor for friendlier import
2020-02-14 11:57:39 -05:00
ethan
1865941b14 #50 update: keep main() in bin 2020-02-12 18:27:58 -06:00
ethan
03c68561a5 #50 - refactor for friendlier import 2020-02-10 17:22:21 -06:00
Jose Diaz-Gonzalez
196acd0aca Release version 0.28.0 2020-02-03 11:41:34 -05:00
Jose Diaz-Gonzalez
679ac841f6 Merge pull request #143 from smiley/patch-1
Remove deprecated (and removed) "git lfs fetch" flags
2020-02-03 11:41:10 -05:00
Jose Diaz-Gonzalez
498d9eba32 Release version 0.27.0 2020-01-21 21:29:44 -05:00
Jose Diaz-Gonzalez
0f82b1717c Merge pull request #142 from einsteinx2/issue/141-import-error-version
Fixed script fails if not installed from pip
2020-01-21 21:28:22 -05:00
Ben Baron
4d5126f303 Fixed script fails if not installed from pip
At the top of the script, the line from github_backup import __version__ gets the script's version number to use if the script is called with the -v or --version flags. The problem is that if the script hasn't been installed via pip (for example I cloned the repo directly to my backup server), the script will fail due to an import exception.

Also presumably it will always use the version number from pip even if running a modified version from git or a fork or something, though this does not fix that as I have no idea how to check if it's running the pip installed version or not. But at least the script will now work fine if cloned from git or just copied to another machine.

closes https://github.com/josegonzalez/python-github-backup/issues/141
2020-01-21 21:15:57 -05:00
smiley
b864218b44 Remove deprecated (and removed) git lfs flags
"--tags" and "--force" were removed at some point from "git lfs fetch". This broke our backup script.
2020-01-20 15:40:52 +02:00
Jose Diaz-Gonzalez
98919c82c9 Merge pull request #136 from einsteinx2/issue/88-macos-keychain-broken-python3
Fixed macOS keychain access when using Python 3
2020-01-07 11:44:36 -05:00
Jose Diaz-Gonzalez
045eacbf18 Merge pull request #137 from einsteinx2/issue/134-only-use-auth-token-when-needed
Public repos no longer include the auth token
2020-01-07 11:44:23 -05:00
Jose Diaz-Gonzalez
7a234ba7ed Merge pull request #130 from einsteinx2/issue/129-fix-crash-on-release-asset-download-error
Crash when an release asset doesn't exist
2020-01-07 11:44:00 -05:00
Ben Baron
e8a255b450 Public repos no longer include the auth token
When backing up repositories using an auth token and https, the GitHub personal auth token is leaked in each backed up repository. It is included in the URL of each repository's git remote url.

This is not needed as they are public and can be accessed without the token and can cause issues in the future if the token is ever changed, so I think it makes more sense not to have the token stored in each repo backup. I think the token should only be "leaked" like this out of necessity, e.g. it's a private repository and the --prefer-ssh option was not chosen so https with auth token was required to perform the clone.
2020-01-06 21:25:54 -05:00
Ben Baron
81a2f762da Fixed macOS keychain access when using Python 3
Python 3 is returning bytes rather than a string, so the string concatenation to create the auth variable was throwing an exception which the script was interpreting to mean it couldn't find the password. Adding a conversion to string first fixed the issue.
2020-01-06 21:10:50 -05:00
Ben Baron
cb0293cbe5 Fixed comment typo 2020-01-06 14:15:41 -05:00
Jose Diaz-Gonzalez
252c25461f Merge pull request #132 from einsteinx2/issue/126-prevent-overwriting-release-assets
Separate release assets and skip re-downloading
2020-01-06 13:12:33 -05:00
Jose Diaz-Gonzalez
e8ed03fd06 Merge pull request #131 from einsteinx2/improve-gitignore
Improved gitignore, macOS files and IDE configs
2020-01-06 13:11:06 -05:00
Ben Baron
38010d7c39 Switched log_info to log_warning in download_file 2020-01-06 13:06:22 -05:00
Ben Baron
71b4288e6b Added newline to end of file 2020-01-06 13:04:40 -05:00
Ben Baron
ba4fa9fa2d Moved asset downloading loop inside the if block 2020-01-06 12:50:33 -05:00
Ben Baron
869f761c90 Separate release assets and skip re-downloading
Currently the script puts all release assets into the same folder called `releases`. So any time 2 release files have the same name, only the last one downloaded is actually saved. A particularly bad example of this is MacDownApp/macdown where all of their releases are named `MacDown.app.zip`. So even though they have 36 releases and all 36 are downloaded, only the last one is actually saved.

With this change, each releases' assets are now stored in a fubfolder inside `releases` named after the release name. There could still be edge cases if two releases have the same name, but this is still much safer tha the previous behavior.

This change also now checks if the asset file already exists on disk and skips downloading it. This drastically speeds up addiotnal syncs as it no longer downloads every single release every single time. It will now only download new releases which I believe is the expected behavior.

closes https://github.com/josegonzalez/python-github-backup/issues/126
2020-01-06 12:40:47 -05:00
Ben Baron
195e700128 Improved gitignore, macOS files and IDE configs
Ignores the annoying hidden macOS files .DS_Store and ._* as well as the IDE configuration folders for contributors using the popular Visual Studio Code and Atom IDEs (more can be added later as needed).
2020-01-06 11:26:06 -05:00
Ben Baron
27441b71b6 Crash when an release asset doesn't exist
Currently, the script crashes whenever a release asset is unable to download (for example a 404 response). This change instead logs the failure and allows the script to continue. No retry logic is enabled, but at least it prevents the crash and allows the backup to complete. Retry logic can be implemented later if wanted.

closes https://github.com/josegonzalez/python-github-backup/issues/129
2020-01-06 11:13:25 -05:00
Jose Diaz-Gonzalez
cfeaee7309 Update ISSUE_TEMPLATE.md 2020-01-06 10:20:07 -05:00
Jose Diaz-Gonzalez
fac8e4274f Release version 0.26.0 2019-09-23 11:45:01 -04:00
Jose Diaz-Gonzalez
17fee66f31 Merge pull request #128 from Snawoot/master
Workaround gist clone in `--prefer-ssh` mode
2019-09-23 11:44:21 -04:00
Vladislav Yarmak
a56d27dd8b workaround gist clone in --prefer-ssh mode 2019-09-21 19:22:27 +03:00
Jose Diaz-Gonzalez
e57873b6dd Create PULL_REQUEST.md 2019-08-14 17:51:19 -04:00
Jose Diaz-Gonzalez
2658b039a1 Create ISSUE_TEMPLATE.md 2019-08-14 17:47:47 -04:00
Jose Diaz-Gonzalez
fd684a71fb Update README.rst 2019-07-11 13:40:25 -07:00
Jose Diaz-Gonzalez
bacd77030b Update README.rst 2019-07-11 13:39:41 -07:00
Jose Diaz-Gonzalez
b73079daf2 Release version 0.25.0 2019-07-03 17:46:12 -04:00
Jose Diaz-Gonzalez
eca8a70666 Merge pull request #120 from 8h2a/patch-1
Issue 119: Change retrieve_data to be a generator
2019-07-03 17:45:40 -04:00
2a
e74765ba7f Issue 119: Change retrieve_data to be a generator
See issue #119.
2019-07-03 23:01:00 +02:00
Jose Diaz-Gonzalez
6db5bd731b Release version 0.24.0 2019-06-27 11:24:43 -04:00
Jose Diaz-Gonzalez
7305871c20 Merge pull request #117 from QuicketSolutions/master
Add option for Releases
2019-06-27 11:15:02 -04:00
Ethan Timm
baf7b1a9b4 Merge pull request #5 from QuicketSolutions/QKT-45
QKT-45: include assets - update readme
2019-06-25 15:41:11 -05:00
Ethan Timm
121fa68294 QKT-45: include assets - update readme
update readme with flag information for including assets alongside their respective releases
2019-06-25 15:41:02 -05:00
Ethan Timm
44dfc79edc Merge pull request #4 from whwright/wip-releases
Download github assets
2019-06-25 15:35:39 -05:00
Harrison Wright
89f59cc7a2 Make assets it's own flag 2019-06-24 15:49:19 -05:00
Jose Diaz-Gonzalez
ad8c5b8768 Merge pull request #118 from whwright/115-fix-pull-details
Fix pull details
2019-06-24 14:51:10 -04:00
Harrison Wright
921aab3729 Fix pull details 2019-06-22 13:19:45 -05:00
Harrison Wright
ea4c3d0f6f Fix super call for python2 2019-06-22 13:05:54 -05:00
Harrison Wright
9b6400932d Fix redirect to s3 2019-06-22 13:00:42 -05:00
Harrison Wright
de0c3f46c6 WIP: download assets 2019-06-21 20:03:14 -05:00
Ethan Timm
73b069f872 Merge pull request #3 from QuicketSolutions/QKT-42
QKT-42: releases - add readme info
2019-06-21 16:54:28 -05:00
ethan
3d3f512074 QKT-42: releases - add readme info 2019-06-21 16:53:40 -05:00
Ethan Timm
1c3078992d Merge pull request #2 from QuicketSolutions/QKT-42
QKT-42 update: shorter command flag
2019-06-21 16:49:40 -05:00
ethan
4b40ae94d7 QKT-42 update: shorter command flag 2019-06-21 16:48:25 -05:00
Ethan Timm
a18fda9faf Merge pull request #1 from QuicketSolutions/QKT-42
QKT-42: support saving release information
2019-06-21 16:43:48 -05:00
ethan
41130fc8b0 QKT-42: support saving release information 2019-06-21 11:20:32 -05:00
Jose Diaz-Gonzalez
2340a02fc6 Release version 0.23.0 2019-06-04 14:43:32 -04:00
Jose Diaz-Gonzalez
cafff4ae80 Merge pull request #113 from kleag/master
Avoid to crash in case of HTTP 502 error
2019-06-04 14:43:10 -04:00
Gael de Chalendar
3193d120e5 Avoid to crash in case of HTTP 502 error
Survive also on socket.error connections like on HTTPError or URLError.

This should solve issue #110.
2019-06-04 18:53:58 +02:00
Jose Diaz-Gonzalez
da4b29a2d6 Release version 0.22.2 2019-02-21 15:41:11 -05:00
Jose Diaz-Gonzalez
d05c96ecef Merge pull request #107 from josegonzalez/patch-1
fix: warn instead of error
2019-02-21 15:40:59 -05:00
Jose Diaz-Gonzalez
c86163bfe6 fix: warn instead of error
Refs #106
2019-02-21 15:40:39 -05:00
Jose Diaz-Gonzalez
eff6e36974 Release version 0.22.1 2019-02-21 15:13:31 -05:00
Jose Diaz-Gonzalez
63e458bafb Merge pull request #106 from jstetic/master
Log URL error
2019-02-21 15:13:02 -05:00
JOHN STETIC
57ab5ce1a2 Log URL error https://github.com/josegonzalez/python-github-backup/issues/105 2019-02-20 20:43:00 -05:00
Jose Diaz-Gonzalez
d148f9b900 Release version 0.22.0 2019-02-01 09:50:42 -05:00
Jose Diaz-Gonzalez
89ee22c2be Merge pull request #103 from whwright/98-better-logging
Fix accidental system exit with better logging strategy
2018-12-27 15:12:26 -05:00
W. Harrison Wright
9e472b74e6 Remove unnecessary sys.exit call 2018-12-27 13:07:13 -06:00
W. Harrison Wright
4b459f9af8 Add org check to avoid incorrect log output 2018-12-27 12:58:57 -06:00
W. Harrison Wright
b70ea87db7 Fix accidental system exit with better logging strategy 2018-12-27 12:53:21 -06:00
Jose Diaz-Gonzalez
f8be34562b Release version 0.21.1 2018-12-25 06:28:28 -05:00
Jose Diaz-Gonzalez
ec05204aa9 Merge pull request #101 from ecki/patch-2
Mark options which are not included in --all
2018-12-25 06:27:58 -05:00
Bernd
628f2cbf73 Mark options which are not included in --all
As discussed in Issue #100
2018-12-24 04:19:29 +01:00
Jose Diaz-Gonzalez
38bf438d2f Release version 0.21.0 2018-11-28 01:59:03 -05:00
Jose Diaz-Gonzalez
899cf42b57 Merge pull request #97 from whwright/94-fix-user-repos
Correctly download repos when user arg != authenticated user
2018-11-28 01:58:37 -05:00
W. Harrison Wright
b5972aaaf0 Correctly download repos when user arg != authenticated user 2018-11-11 19:40:46 -06:00
Jose Diaz-Gonzalez
d860f369e9 Release version 0.20.1 2018-09-29 00:16:48 -04:00
Jose Diaz-Gonzalez
77ab1bda15 Merge pull request #92 from whwright/87-fix-starred-bug
Clone the specified user's starred repos/gists, not the authenticated user
2018-09-29 00:16:32 -04:00
W. Harrison Wright
4a4a317331 Clone the specified user's gists, not the authenticated user 2018-09-28 21:59:50 -05:00
W. Harrison Wright
5a8e1ac275 Clone the specified user's starred repos, not the authenticated user 2018-09-28 21:46:28 -05:00
Jose Diaz-Gonzalez
0de341eab4 Release version 0.20.0 2018-03-24 15:00:26 -04:00
Jose Diaz-Gonzalez
b0130fdf94 chore: drop Python 2.6 2018-03-24 15:00:05 -04:00
Jose Diaz-Gonzalez
b49f399037 feat: simplify release script 2018-03-24 14:59:56 -04:00
Jose Diaz-Gonzalez
321414d352 Release version 0.19.2 2018-03-24 01:16:34 -04:00
Jose Diaz-Gonzalez
413d4381cc fix: cleanup pep8 violations 2018-03-24 01:16:28 -04:00
Jose Diaz-Gonzalez
0110ea40ed Release version 0.19.1 2018-03-24 01:04:35 -04:00
Jose Diaz-Gonzalez
8d2ef2f528 Release version 0.19.0 2018-03-24 00:54:34 -04:00
Jose Diaz-Gonzalez
1a79f755a5 Merge pull request #77 from mayflower/pull-details
Pull Details
2018-03-23 23:40:22 -04:00
Jose Diaz-Gonzalez
abf45d5b54 Merge pull request #84 from johbo/fix-python36-skip-existing
Mark string as binary in comparison for skip_existing
2018-02-26 10:44:12 -05:00
Johannes Bornhold
fd33037b1c Mark string as binary in comparison for skip_existing
Found out that the flag "--skip-existing" did not work out as expected on Python
3.6. Tracked it down to the comparison which has to be against a string of bytes
in Python3.
2018-02-26 11:21:25 +01:00
Jose Diaz-Gonzalez
87dab293ed Release version 0.18.0 2018-02-22 12:13:06 -05:00
Jose Diaz-Gonzalez
0244af4e05 Merge pull request #82 from sgreene570/add-followers
Add option to fetch followers/following JSON data
2018-02-22 12:11:48 -05:00
Stephen Greene
eca9f0f7df Add option to fetch followers/following JSON data 2018-02-21 19:29:59 -08:00
Jose Diaz-Gonzalez
afa2a6d587 Release version 0.17.0 2018-02-20 13:06:48 -05:00
Jose Diaz-Gonzalez
b77ea48d74 Merge pull request #81 from whwright/gists
Add ability to back up gists
2018-02-19 15:29:20 -05:00
W. Harrison Wright
f378254188 Short circuit gists backup process 2018-02-07 21:46:59 -06:00
W. Harrison Wright
83128e986a Formatting 2018-02-07 21:30:55 -06:00
W. Harrison Wright
17e4f9a125 Add ability to backup gists 2018-02-07 21:29:49 -06:00
Jose Diaz-Gonzalez
e59d1e3a68 Release version 0.16.0 2018-01-22 12:49:31 -05:00
Jose Diaz-Gonzalez
de860ee5a9 Merge pull request #78 from whwright/clone-starred-repos
Clone starred repos
2018-01-22 12:36:42 -05:00
Jose Diaz-Gonzalez
cb054c2631 Update README.rst 2018-01-22 12:36:32 -05:00
W. Harrison Wright
c142707a90 Update documentation 2018-01-22 11:34:27 -06:00
W. Harrison Wright
7cccd42ec9 Change option to --all-starred 2018-01-14 10:22:10 -06:00
W. Harrison Wright
9a539b1d6b JK don't update documentation 2018-01-14 10:18:51 -06:00
W. Harrison Wright
cd2372183e Update documentation 2018-01-13 17:44:09 -06:00
W. Harrison Wright
bd346de898 Put starred clone repoistories under a new option 2018-01-13 17:43:00 -06:00
W. Harrison Wright
6e3cbe841a Add comment 2018-01-13 14:12:26 -06:00
W. Harrison Wright
8b95f187ad Add ability to clone starred repos 2018-01-13 14:08:36 -06:00
Robin Gloster
ef88248c41 Add additional output for the current request
This is useful to have some progress indication for huge repositories.
2017-12-29 23:33:53 +01:00
Robin Gloster
0a4decfb3b Add option to backup additional PR details
Some payload is only included when requesting a single pull request
2017-12-29 21:39:59 +01:00
Jose Diaz-Gonzalez
2b9549ffde Release version 0.15.0 2017-12-11 11:46:16 -05:00
Jose Diaz-Gonzalez
fb2c3ca921 Merge pull request #75 from slibby/slibby-patch-windows
update check_io() to allow scripts to run on Windows
2017-12-11 11:45:58 -05:00
Sam Libby
4f4785085d update logging_subprocess function
1. added newline for return
2. added one-time warning (once per subprocess)
2017-12-11 09:25:49 -07:00
Sam Libby
76895dcf69 update check_io() to allow scripts to run on Windows 2017-12-10 21:44:26 -07:00
Jose Diaz-Gonzalez
1d50a4038b Release version 0.14.1 2017-10-11 16:18:21 -04:00
Jose Diaz-Gonzalez
9d31ccfba9 Merge pull request #70 from epfremmer/patch-1
Fix arg not defined error
2017-10-11 16:17:58 -04:00
Edward Pfremmer
27a1ba2d04 Fix arg not defined error
Ref: https://github.com/josegonzalez/python-github-backup/issues/69
2017-10-11 15:12:34 -05:00
Jose Diaz-Gonzalez
f157ea107f Release version 0.14.0 2017-10-11 11:52:16 -04:00
Jose Diaz-Gonzalez
a129cc759a Merge pull request #68 from pieterclaerhout/master
Added support for LFS clones
2017-10-11 11:51:57 -04:00
pieterclaerhout
bb551a83f4 Updated the readme 2017-10-11 15:14:13 +02:00
pieterclaerhout
9b1b4a9ebc Added a check to see if git-lfs is installed when doing an LFS clone 2017-10-11 15:11:14 +02:00
pieterclaerhout
e6b6eb8bef Added support for LFS clones 2017-10-10 19:52:07 +02:00
Jose Diaz-Gonzalez
0b3f120e2b Merge pull request #66 from albertyw/python3
Explicitly support python 3
2017-09-30 21:01:27 -04:00
Albert Wang
990249b80b Add pypi info to readme 2017-09-30 17:16:38 -07:00
Albert Wang
cefb226545 Explicitly support python 3 in package description 2017-09-30 17:13:47 -07:00
Jose Diaz-Gonzalez
ea22ffdf26 Merge pull request #65 from mumblez/master
add couple examples to help new users
2017-05-30 11:58:42 -06:00
Yusuf Tran
0f21d7b8a4 add couple examples to help new users 2017-05-30 18:52:11 +01:00
Jose Diaz-Gonzalez
cb33b9bab7 Release version 0.13.2 2017-05-06 14:14:08 -06:00
Jose Diaz-Gonzalez
68c48cb0b3 Merge pull request #64 from karlicoss/fix-remotes
Fix remotes while updating repository
2017-05-06 14:13:46 -06:00
Dima Gerasimov
922a3c5a6e Fix remotes while updating repository 2017-05-06 12:58:42 +01:00
Jose Diaz-Gonzalez
d4055eb99c Release version 0.13.1 2017-04-11 09:40:13 -06:00
Jose Diaz-Gonzalez
d8a330559c Merge pull request #61 from McNetic/fix_empty_updated_at
Fix error when repository has no updated_at value
2017-04-11 09:37:15 -06:00
Nicolai Ehemann
de93824498 Fix error when repository has no updated_at value 2017-04-11 11:10:03 +02:00
Jose Diaz-Gonzalez
2efeaa7580 Release version 0.13.0 2017-04-05 11:49:49 -04:00
Jose Diaz-Gonzalez
647810a2f0 Merge pull request #59 from martintoreilly/master
Add support for storing PAT in OSX keychain
2017-04-05 11:49:24 -04:00
Martin O'Reilly
0dfe5c342a Add OS check for OSX specific keychain args
Keychain arguments are only supported on Mac OSX.
Added check for operating system so we give a
"Keychain arguments are only supported on Mac OSX"
error message rather than a "No password item matching the
provided name and account could be found in the osx keychain"
error message
2017-04-05 16:36:52 +01:00
Martin O'Reilly
1d6e1abab1 Add support for storing PAT in OSX keychain
Added additional optional arguments and README guidance for storing
and accessing a Github personal access token (PAT) in the OSX
keychain
2017-04-05 15:17:52 +01:00
Jose Diaz-Gonzalez
dd2b96b172 Release version 0.12.1 2017-03-27 14:55:11 -06:00
Jose Diaz-Gonzalez
7a589f1e63 Merge pull request #57 from acdha/reuse-existing-remotes
Avoid remote branch name churn
2017-03-27 14:54:02 -06:00
Chris Adams
92c619cd01 Avoid remote branch name churn
This avoids the backup output having lots of "[new branch]" messages
because removing the old remote name removed all of the existing branch
references.
2017-03-27 16:26:19 -04:00
Jose Diaz-Gonzalez
9a91dd7733 Merge pull request #55 from amaczuga/master
Fix detection of bare git directories
2016-11-22 13:36:52 -07:00
Andrzej Maczuga
6592bd8196 Fix detection of bare git directories 2016-11-22 20:11:26 +00:00
Jose Diaz-Gonzalez
e9e3b18512 Release version 0.12.0 2016-11-22 10:56:56 -07:00
Jose Diaz-Gonzalez
88148b4c95 pep8: E501 line too long (83 > 79 characters) 2016-11-22 10:55:37 -07:00
Jose Diaz-Gonzalez
8448add464 pep8: E128 continuation line under-indented for visual indent 2016-11-22 10:51:04 -07:00
Jose Diaz-Gonzalez
5b30b7ebdd fix: properly import version from github_backup package 2016-11-22 10:49:18 -07:00
Jose Diaz-Gonzalez
c3a17710d3 fix: support alternate git status output 2016-11-22 10:48:07 -07:00
Jose Diaz-Gonzalez
4462412ec7 Merge pull request #54 from amaczuga/master
Support archivization using bare git clones
2016-11-22 09:44:54 -07:00
Andrzej Maczuga
8d61538e5e Support archivization using bare git clones 2016-11-22 13:07:52 +00:00
Jose Diaz-Gonzalez
4d37ad206f Merge pull request #53 from trel/master
fix typo, 3x
2016-11-18 15:35:53 -05:00
Terrell Russell
1f983863fc fix typo, 3x 2016-11-18 15:17:42 -05:00
Jose Diaz-Gonzalez
f0b28567b9 Release version 0.11.0 2016-10-26 14:14:00 -06:00
Jose Diaz-Gonzalez
77ede50b19 Merge pull request #52 from bjodah/fix-gh-51
Support --token file:///home/user/token.txt (fixes gh-51)
2016-10-26 14:13:35 -06:00
Björn Dahlgren
97e4fbbacb Support --token file:///home/user/token.txt (fixes gh-51) 2016-10-26 01:57:33 +02:00
Jose Diaz-Gonzalez
03604cc654 Merge pull request #48 from albertyw/python3
Support Python 3
2016-10-25 17:38:05 -06:00
Albert Wang
73a62fdee1 Fix some linting 2016-09-11 01:14:36 -07:00
Albert Wang
94e1d62ad5 Fix byte/string conversion for python 3 2016-09-11 01:14:31 -07:00
Albert Wang
54cef11ce7 Support python 3 2016-09-11 01:14:19 -07:00
Jose Diaz-Gonzalez
56397eba1c Merge pull request #46 from remram44/encode-password
Encode special characters in password
2016-09-06 14:31:35 -04:00
Remi Rampin
9f861efccf Encode special characters in password 2016-09-06 14:27:47 -04:00
Jose Diaz-Gonzalez
c1c9ce6dca Merge pull request #45 from remram44/cli-programname
Fix program name
2016-09-06 12:42:45 -04:00
Jose Diaz-Gonzalez
ab18d8aee0 Merge pull request #44 from remram44/readme-git-https
Don't install over insecure connection
2016-09-06 12:42:30 -04:00
Remi Rampin
9d7d98b19e Update README.rst 2016-09-06 12:28:44 -04:00
Remi Rampin
0233bff696 Don't pretend program name is "Github Backup" 2016-09-06 12:24:51 -04:00
Remi Rampin
6154ceda15 Don't install over insecure connection
The git:// protocol is unauthenticated and unencrypted, and no longer advertised by GitHub. Using HTTPS shouldn't impact performance.
2016-09-06 12:11:29 -04:00
Jose Diaz-Gonzalez
9023052e9c Release version 0.10.3 2016-08-20 20:50:29 -04:00
Jose Diaz-Gonzalez
874c235ba5 Merge pull request #30 from jonasrmichel/master
Fixes #29
2016-08-20 20:50:25 -04:00
Jose Diaz-Gonzalez
b7b234d8a5 Release version 0.10.2 2016-08-20 20:49:46 -04:00
Jose Diaz-Gonzalez
ed160eb0ca Add a note regarding git version requirement
Closes #37
2016-08-20 20:49:42 -04:00
Jose Diaz-Gonzalez
1d11d62b73 Release version 0.10.1 2016-08-20 20:45:27 -04:00
Jose Diaz-Gonzalez
9e1cba9817 Release version 0.10.0 2016-08-18 14:20:46 -04:00
Jose Diaz-Gonzalez
3859a80b7a Merge pull request #42 from robertwb/master
Implement incremental updates
2016-08-18 14:20:05 -04:00
Robert Bradshaw
8c12d54898 Implement incremental updates
Guarded with an --incremental flag.

Stores the time of the last update and only downloads issue and
pull request data since this time.  All other data is relatively
small (likely fetched with a single request) and so is simply
re-populated from scratch as before.
2016-08-17 21:31:59 -07:00
Jonas Michel
1e5a90486c Fixes #29
Reporting an error when the user's rate limit is exceeded causes
the script to terminate after resuming execution from a rate limit
sleep. Instead of generating an explicit error we just want to
inform the user that the script is going to sleep until their rate
limit count resets.
2016-01-20 14:48:02 -06:00
Jonas Michel
9b74aff20b Fixes #29
The errors list was not being cleared out after resuming a backup
from a rate limit sleep. When the backup was resumed, the non-empty
errors list caused the backup to quit after the next `retrieve_data`
request.
2016-01-17 11:10:28 -06:00
16 changed files with 2665 additions and 853 deletions

117
.gitchangelog.rc Normal file
View File

@@ -0,0 +1,117 @@
#
# Format
#
# ACTION: [AUDIENCE:] COMMIT_MSG [@TAG ...]
#
# Description
#
# ACTION is one of 'chg', 'fix', 'new'
#
# Is WHAT the change is about.
#
# 'chg' is for refactor, small improvement, cosmetic changes...
# 'fix' is for bug fixes
# 'new' is for new features, big improvement
#
# SUBJECT is optional and one of 'dev', 'usr', 'pkg', 'test', 'doc'
#
# Is WHO is concerned by the change.
#
# 'dev' is for developpers (API changes, refactors...)
# 'usr' is for final users (UI changes)
# 'pkg' is for packagers (packaging changes)
# 'test' is for testers (test only related changes)
# 'doc' is for doc guys (doc only changes)
#
# COMMIT_MSG is ... well ... the commit message itself.
#
# TAGs are additionnal adjective as 'refactor' 'minor' 'cosmetic'
#
# 'refactor' is obviously for refactoring code only
# 'minor' is for a very meaningless change (a typo, adding a comment)
# 'cosmetic' is for cosmetic driven change (re-indentation, 80-col...)
#
# Example:
#
# new: usr: support of bazaar implemented
# chg: re-indentend some lines @cosmetic
# new: dev: updated code to be compatible with last version of killer lib.
# fix: pkg: updated year of licence coverage.
# new: test: added a bunch of test around user usability of feature X.
# fix: typo in spelling my name in comment. @minor
#
# Please note that multi-line commit message are supported, and only the
# first line will be considered as the "summary" of the commit message. So
# tags, and other rules only applies to the summary. The body of the commit
# message will be displayed in the changelog with minor reformating.
#
# ``ignore_regexps`` is a line of regexps
#
# Any commit having its full commit message matching any regexp listed here
# will be ignored and won't be reported in the changelog.
#
ignore_regexps = [
r'(?i)^(Merge pull request|Merge branch|Release|Update)',
]
#
# ``replace_regexps`` is a dict associating a regexp pattern and its replacement
#
# It will be applied to get the summary line from the full commit message.
#
# Note that you can provide multiple replacement patterns, they will be all
# tried. If None matches, the summary line will be the full commit message.
#
replace_regexps = {
# current format (ie: 'chg: dev: my commit msg @tag1 @tag2')
r'^([cC]hg|[fF]ix|[nN]ew)\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n@]*)(@[a-z]+\s+)*$':
r'\4',
}
# ``section_regexps`` is a list of 2-tuples associating a string label and a
# list of regexp
#
# Commit messages will be classified in sections thanks to this. Section
# titles are the label, and a commit is classified under this section if any
# of the regexps associated is matching.
#
section_regexps = [
('New', [
r'^[nN]ew\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$',
]),
('Changes', [
r'^[cC]hg\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$',
]),
('Fix', [
r'^[fF]ix\s*:\s*((dev|use?r|pkg|test|doc)\s*:\s*)?([^\n]*)$',
]),
('Other', None # Match all lines
),
]
# ``body_split_regexp`` is a regexp
#
# Commit message body (not the summary) if existing will be split
# (new line) on this regexp
#
body_split_regexp = r'[\n-]'
# ``tag_filter_regexp`` is a regexp
#
# Tags that will be used for the changelog must match this regexp.
#
# tag_filter_regexp = r'^[0-9]+$'
tag_filter_regexp = r'^(?:[vV])?[0-9\.]+$'
# ``unreleased_version_label`` is a string
#
# This label will be used as the changelog Title of the last set of changes
# between last valid tag and HEAD if any.
unreleased_version_label = "%%version%% (unreleased)"

41
.github/workflows/automatic-release.yml vendored Normal file
View File

@@ -0,0 +1,41 @@
name: automatic-release
on:
workflow_dispatch:
inputs:
release_type:
description: Release type
required: true
type: choice
options:
- patch
- minor
- major
jobs:
release:
name: Release
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
ssh-key: ${{ secrets.DEPLOY_PRIVATE_KEY }}
- name: Setup Git
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.8'
- name: Install prerequisites
run: pip install -r release-requirements.txt
- name: Execute release
env:
SEMVER_BUMP: ${{ github.event.inputs.release_type }}
TWINE_REPOSITORY: ${{ vars.TWINE_REPOSITORY }}
TWINE_USERNAME: ${{ secrets.TWINE_USERNAME }}
TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }}
run: ./release $SEMVER_BUMP

32
.github/workflows/lint.yml vendored Normal file
View File

@@ -0,0 +1,32 @@
---
name: "lint"
# yamllint disable-line rule:truthy
on:
pull_request:
branches:
- '*'
push:
branches:
- 'main'
- 'master'
jobs:
lint:
name: lint
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: "3.8"
cache: "pip"
- run: pip install -r release-requirements.txt
- run: flake8 --ignore=E501,E203,W503
- run: black .
- run: rst-lint README.rst

19
.github/workflows/tagged-release.yml vendored Normal file
View File

@@ -0,0 +1,19 @@
---
name: "tagged-release"
# yamllint disable-line rule:truthy
on:
push:
tags:
- '*'
jobs:
tagged-release:
name: tagged-release
runs-on: ubuntu-20.04
steps:
- uses: "marvinpinto/action-automatic-releases@v1.2.1"
with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
prerelease: false

10
.gitignore vendored
View File

@@ -25,3 +25,13 @@ doc/_build
# Generated man page
doc/aws_hostname.1
# Annoying macOS files
.DS_Store
._*
# IDE configuration files
.vscode
.atom
README

View File

@@ -1,14 +1,631 @@
Changelog
=========
0.44.1 (2023-12-09)
-------------------
------------------------
Fix
~~~
- Use a deploy key to push tags so releases get auto-created. [Jose
Diaz-Gonzalez]
Other
~~~~~
- Chore(deps): bump certifi from 2023.5.7 to 2023.7.22.
[dependabot[bot]]
Bumps [certifi](https://github.com/certifi/python-certifi) from 2023.5.7 to 2023.7.22.
- [Commits](https://github.com/certifi/python-certifi/compare/2023.05.07...2023.07.22)
---
updated-dependencies:
- dependency-name: certifi
dependency-type: direct:production
...
- Tests: run lint on pull requests. [Jose Diaz-Gonzalez]
- Chore(deps): bump urllib3 from 2.0.2 to 2.0.7. [dependabot[bot]]
Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.0.2 to 2.0.7.
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/2.0.2...2.0.7)
---
updated-dependencies:
- dependency-name: urllib3
dependency-type: direct:production
...
- Chore: remove circleci as tests now run in github actions. [Jose Diaz-
Gonzalez]
- Tests: install correct dependencies and rename job. [Jose Diaz-
Gonzalez]
- Tests: add lint github action workflow. [Jose Diaz-Gonzalez]
- Feat: install autopep8. [Jose Diaz-Gonzalez]
- Chore(deps): bump certifi from 2023.5.7 to 2023.7.22.
[dependabot[bot]]
Bumps [certifi](https://github.com/certifi/python-certifi) from 2023.5.7 to 2023.7.22.
- [Commits](https://github.com/certifi/python-certifi/compare/2023.05.07...2023.07.22)
---
updated-dependencies:
- dependency-name: certifi
dependency-type: direct:production
...
- Chore: reformat file and update flake8. [Jose Diaz-Gonzalez]
0.44.0 (2023-12-09)
-------------------
Fix
~~~
- Do not use raw property in readme. [Jose Diaz-Gonzalez]
This is disabled on pypi.
- Validate release before committing and uploading it. [Jose Diaz-
Gonzalez]
- Correct lint issues and show errors on lint. [Jose Diaz-Gonzalez]
- Minor cosmetic changes. [ZhymabekRoman]
- Add forgotten variable formatting. [ZhymabekRoman]
- Refactor logging Based on #195. [ZhymabekRoman]
- Minor typo fix. [Zhymabek Roman]
Other
~~~~~
- Bump certifi from 2023.5.7 to 2023.7.22. [dependabot[bot]]
Bumps [certifi](https://github.com/certifi/python-certifi) from 2023.5.7 to 2023.7.22.
- [Commits](https://github.com/certifi/python-certifi/compare/2023.05.07...2023.07.22)
---
updated-dependencies:
- dependency-name: certifi
dependency-type: direct:production
...
- Checkout everything. [Halvor Holsten Strand]
- Added automatic release workflow, for use with GitHub Actions. [Halvor
Holsten Strand]
- Feat: create Dockerfile. [Tom Plant]
- Fix rst html. [hozza]
- Add contributor section. [hozza]
- Fix readme wording and format. [hozza]
- Fixed readme working and layout. [hozza]
- Fix readme formatting, spelling and layout. [hozza]
- Added details usage and examples including gotchas, errors and
development instructions. [hozza]
- Added verbose install instructions. [hozza]
- Bump urllib3 from 2.0.2 to 2.0.7. [dependabot[bot]]
Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.0.2 to 2.0.7.
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/2.0.2...2.0.7)
---
updated-dependencies:
- dependency-name: urllib3
dependency-type: direct:production
...
- Suggested modification to fix win32 logging failure, due to local
variable scope. Logger does not appear to have any utility within
"logging_subprocess". [Halvor Holsten Strand]
- Simplified one if/elif scenario. Extracted file reading of another
if/elif scenario. [Halvor Holsten Strand]
- Ran black. [Halvor Holsten Strand]
- Keep backwards compatability by going back to "--token" for classic.
Allow "file://" uri for "--token-fine". [Halvor Holsten Strand]
- Add support for fine-grained tokens. [froggleston]
- Refactor logging and add support for quiet flag. [Harrison Wright]
0.43.1 (2023-05-29)
-------------------
- Chore: add release requirements. [Jose Diaz-Gonzalez]
0.43.0 (2023-05-29)
-------------------
Fix
~~~
- Do not update readme. [Jose Diaz-Gonzalez]
- Adjust for black. [Jose Diaz-Gonzalez]
- Adjust for black. [Jose Diaz-Gonzalez]
- Adjust for black. [Jose Diaz-Gonzalez]
Other
~~~~~
- Feat: commit gitchangelog.rc to repo so anyone can generate a
changelog. [Jose Diaz-Gonzalez]
- Feat: add release tagging. [Jose Diaz-Gonzalez]
- Chore: formatting. [Jose Diaz-Gonzalez]
- Chore: run black. [Jose Diaz-Gonzalez]
- Add --log-level command line argument. [Enrico Tröger]
Support changing the log level to the desired value easily.
For example, this is useful to suppress progress messages but
keep logging warnings and errors.
- Check both updated_at and pushed_at properties. [Ken Bailey]
Check both updated_at and pushed_at dates to get the last_update to reduce data retrieved on incremental api calls using since.
0.42.0 (2022-11-28)
-------------------
- Add option to exclude repositories. [npounder]
- Backup regular pull request comments as well. [Oneric]
Before, only review comments were backed up;
regular comments need to be fetched via issue API.
- Fix bug forever retry when request url error. [kornpisey]
- Added --no-prune option to disable prune option when doing git fetch.
[kornpisey]
0.41.0 (2022-03-02)
-------------------
- Git lfs clone doe snot respect --mirror. [Louis Parisot]
0.40.2 (2021-12-29)
-------------------
- Fix lint issues raised by Flake8. [atinary-afoulon]
According to job:
[ https://app.circleci.com/pipelines/github/josegonzalez/python-github-backup/30/workflows/74eb93f2-2505-435d-b728-03b3cc04c14a/jobs/23 ]
Failed on the following checks:
./github_backup/github_backup.py:20:1: F811 redefinition of unused 'logging' from line 14
./github_backup/github_backup.py:45:1: E302 expected 2 blank lines, found 1
./github_backup/github_backup.py:136:20: E251 unexpected spaces around keyword / parameter equals
0.40.1 (2021-09-22)
-------------------
- Revert to fetch. [Harrison Wright]
0.40.0 (2021-07-12)
-------------------
- Add retry on certain network errors. [Jacek Nykis]
This change includes certain network level errors in the retry logic.
It partially address #110 but I think more comprehensive fix would be useful.
- Pull changes from remote. [Jonas]
use `git pull` to pull actual files from the remote instead of using `fetch` for only the metadata
0.39.0 (2021-03-19)
-------------------
Fix
~~~
- Fix missing INFO logs. [Gallo Feliz]
Other
~~~~~
- Try to make compatible code with direct Python call ; reduce the hard
link of the code with the cli. [Gallo Feliz]
- Fixed release_name with slash bug. [Álvaro Torres Cogollo]
0.38.0 (2021-02-13)
-------------------
Fix
~~~
- Always clone with OAuth token when provided. [Samantha Baldwin]
Github Enterprise servers with 'Anonymous Git read access' disabled
cause `git ls-remote` to fail (128) for a repo's `clone_url`. Using the
OAuth token when provided allows cloning private AND public repos when
Anonymous Git read access is disabled.
Other
~~~~~
- Change broken link to a fork to a working link to upstream. [Rick van
Schijndel]
0.37.2 (2021-01-02)
-------------------
Fix
~~~
- Use distutils.core on error. [Jose Diaz-Gonzalez]
0.37.1 (2021-01-02)
-------------------
Fix
~~~
- Use twine for releases. [Jose Diaz-Gonzalez]
The old method of releasing to pypi broke for whatever reason and switching to a supported toolchain is easier than debugging the old one.
Additionally:
- Update gitchangelog
- Fix license entry
- Set long description type
- Gitignore the temporary readme file
0.37.0 (2021-01-02)
-------------------
- Add support for python 3.7 and 3.8 in package classifiers. [Albert
Wang]
- Remove support for python 2.7 in package classifiers. [Albert Wang]
- Remove python 2 specific import logic. [Albert Wang]
- Remove python 2 specific logic. [Albert Wang]
- Add ability to skip archived repositories. [Gary Moon]
0.36.0 (2020-08-29)
-------------------
- Add flake8 instructions to readme. [Albert Wang]
- Fix regex string. [Albert Wang]
- Fix whitespace issues. [Albert Wang]
- Do not use bare excepts. [Albert Wang]
- Add .circleci/config.yml. [Albert Wang]
- Include --private flag in example. [wouter bolsterlee]
By default, private repositories are not included. This is surprising.
It took me a while to figure this out, and making that clear in the
example can help others to be aware of that.
0.35.0 (2020-08-05)
-------------------
- Make API request throttling optional. [Samantha Baldwin]
0.34.0 (2020-07-24)
-------------------
- Add logic for transforming gist repository urls to ssh. [Matt Fields]
0.33.0 (2020-04-13)
-------------------
- Add basic API request throttling. [Enrico Tröger]
A simple approach to throttle API requests and so keep within the rate
limits of the API. Can be enabled with "--throttle-limit" to specify
when throttling should start.
"--throttle-pause" defines the time to sleep between further API
requests.
0.32.0 (2020-04-13)
-------------------
- Add timestamp to log messages. [Enrico Tröger]
0.31.0 (2020-02-25)
-------------------
- #123 update: changed --as-app 'help' description. [ethan]
- #123: Support Authenticating As Github Application. [ethan]
0.29.0 (2020-02-14)
-------------------
- #50 update: keep main() in bin. [ethan]
- #50 - refactor for friendlier import. [ethan]
0.28.0 (2020-02-03)
-------------------
- Remove deprecated (and removed) git lfs flags. [smiley]
"--tags" and "--force" were removed at some point from "git lfs fetch". This broke our backup script.
0.27.0 (2020-01-22)
-------------------
- Fixed script fails if not installed from pip. [Ben Baron]
At the top of the script, the line from github_backup import __version__ gets the script's version number to use if the script is called with the -v or --version flags. The problem is that if the script hasn't been installed via pip (for example I cloned the repo directly to my backup server), the script will fail due to an import exception.
Also presumably it will always use the version number from pip even if running a modified version from git or a fork or something, though this does not fix that as I have no idea how to check if it's running the pip installed version or not. But at least the script will now work fine if cloned from git or just copied to another machine.
closes https://github.com/josegonzalez/python-github-backup/issues/141
- Fixed macOS keychain access when using Python 3. [Ben Baron]
Python 3 is returning bytes rather than a string, so the string concatenation to create the auth variable was throwing an exception which the script was interpreting to mean it couldn't find the password. Adding a conversion to string first fixed the issue.
- Public repos no longer include the auth token. [Ben Baron]
When backing up repositories using an auth token and https, the GitHub personal auth token is leaked in each backed up repository. It is included in the URL of each repository's git remote url.
This is not needed as they are public and can be accessed without the token and can cause issues in the future if the token is ever changed, so I think it makes more sense not to have the token stored in each repo backup. I think the token should only be "leaked" like this out of necessity, e.g. it's a private repository and the --prefer-ssh option was not chosen so https with auth token was required to perform the clone.
- Fixed comment typo. [Ben Baron]
- Switched log_info to log_warning in download_file. [Ben Baron]
- Crash when an release asset doesn't exist. [Ben Baron]
Currently, the script crashes whenever a release asset is unable to download (for example a 404 response). This change instead logs the failure and allows the script to continue. No retry logic is enabled, but at least it prevents the crash and allows the backup to complete. Retry logic can be implemented later if wanted.
closes https://github.com/josegonzalez/python-github-backup/issues/129
- Moved asset downloading loop inside the if block. [Ben Baron]
- Separate release assets and skip re-downloading. [Ben Baron]
Currently the script puts all release assets into the same folder called `releases`. So any time 2 release files have the same name, only the last one downloaded is actually saved. A particularly bad example of this is MacDownApp/macdown where all of their releases are named `MacDown.app.zip`. So even though they have 36 releases and all 36 are downloaded, only the last one is actually saved.
With this change, each releases' assets are now stored in a fubfolder inside `releases` named after the release name. There could still be edge cases if two releases have the same name, but this is still much safer tha the previous behavior.
This change also now checks if the asset file already exists on disk and skips downloading it. This drastically speeds up addiotnal syncs as it no longer downloads every single release every single time. It will now only download new releases which I believe is the expected behavior.
closes https://github.com/josegonzalez/python-github-backup/issues/126
- Added newline to end of file. [Ben Baron]
- Improved gitignore, macOS files and IDE configs. [Ben Baron]
Ignores the annoying hidden macOS files .DS_Store and ._* as well as the IDE configuration folders for contributors using the popular Visual Studio Code and Atom IDEs (more can be added later as needed).
0.26.0 (2019-09-23)
-------------------
- Workaround gist clone in `--prefer-ssh` mode. [Vladislav Yarmak]
- Create PULL_REQUEST.md. [Jose Diaz-Gonzalez]
- Create ISSUE_TEMPLATE.md. [Jose Diaz-Gonzalez]
0.25.0 (2019-07-03)
-------------------
- Issue 119: Change retrieve_data to be a generator. [2a]
See issue #119.
0.24.0 (2019-06-27)
-------------------
- QKT-45: include assets - update readme. [Ethan Timm]
update readme with flag information for including assets alongside their respective releases
- Make assets it's own flag. [Harrison Wright]
- Fix super call for python2. [Harrison Wright]
- Fix redirect to s3. [Harrison Wright]
- WIP: download assets. [Harrison Wright]
- QKT-42: releases - add readme info. [ethan]
- QKT-42 update: shorter command flag. [ethan]
- QKT-42: support saving release information. [ethan]
- Fix pull details. [Harrison Wright]
0.23.0 (2019-06-04)
-------------------
- Avoid to crash in case of HTTP 502 error. [Gael de Chalendar]
Survive also on socket.error connections like on HTTPError or URLError.
This should solve issue #110.
0.22.2 (2019-02-21)
-------------------
Fix
~~~
- Warn instead of error. [Jose Diaz-Gonzalez]
Refs #106
0.22.1 (2019-02-21)
-------------------
- Log URL error https://github.com/josegonzalez/python-github-
backup/issues/105. [JOHN STETIC]
0.22.0 (2019-02-01)
-------------------
- Remove unnecessary sys.exit call. [W. Harrison Wright]
- Add org check to avoid incorrect log output. [W. Harrison Wright]
- Fix accidental system exit with better logging strategy. [W. Harrison
Wright]
0.21.1 (2018-12-25)
-------------------
- Mark options which are not included in --all. [Bernd]
As discussed in Issue #100
0.21.0 (2018-11-28)
-------------------
- Correctly download repos when user arg != authenticated user. [W.
Harrison Wright]
0.20.1 (2018-09-29)
-------------------
- Clone the specified user's gists, not the authenticated user. [W.
Harrison Wright]
- Clone the specified user's starred repos, not the authenticated user.
[W. Harrison Wright]
0.20.0 (2018-03-24)
-------------------
- Chore: drop Python 2.6. [Jose Diaz-Gonzalez]
- Feat: simplify release script. [Jose Diaz-Gonzalez]
0.19.2 (2018-03-24)
-------------------
Fix
~~~
- Cleanup pep8 violations. [Jose Diaz-Gonzalez]
0.19.0 (2018-03-24)
-------------------
- Add additional output for the current request. [Robin Gloster]
This is useful to have some progress indication for huge repositories.
- Add option to backup additional PR details. [Robin Gloster]
Some payload is only included when requesting a single pull request
- Mark string as binary in comparison for skip_existing. [Johannes
Bornhold]
Found out that the flag "--skip-existing" did not work out as expected on Python
3.6. Tracked it down to the comparison which has to be against a string of bytes
in Python3.
0.18.0 (2018-02-22)
-------------------
- Add option to fetch followers/following JSON data. [Stephen Greene]
0.17.0 (2018-02-20)
-------------------
- Short circuit gists backup process. [W. Harrison Wright]
- Formatting. [W. Harrison Wright]
- Add ability to backup gists. [W. Harrison Wright]
0.16.0 (2018-01-22)
-------------------
- Change option to --all-starred. [W. Harrison Wright]
- JK don't update documentation. [W. Harrison Wright]
- Put starred clone repoistories under a new option. [W. Harrison
Wright]
- Add comment. [W. Harrison Wright]
- Add ability to clone starred repos. [W. Harrison Wright]
0.14.1 (2017-10-11)
-------------------
- Fix arg not defined error. [Edward Pfremmer]
0.14.0 (2017-10-11)
-------------------
- Added a check to see if git-lfs is installed when doing an LFS clone.
[pieterclaerhout]
- Added support for LFS clones. [pieterclaerhout]
- Add pypi info to readme. [Albert Wang]
- Explicitly support python 3 in package description. [Albert Wang]
- Add couple examples to help new users. [Yusuf Tran]
0.13.2 (2017-05-06)
-------------------
- Fix remotes while updating repository. [Dima Gerasimov]
0.13.1 (2017-04-11)
-------------------
- Fix error when repository has no updated_at value. [Nicolai Ehemann]
0.13.0 (2017-04-05)
-------------------
- Add OS check for OSX specific keychain args. [Martin O'Reilly]
Keychain arguments are only supported on Mac OSX.
Added check for operating system so we give a
"Keychain arguments are only supported on Mac OSX"
error message rather than a "No password item matching the
provided name and account could be found in the osx keychain"
error message
- Add support for storing PAT in OSX keychain. [Martin O'Reilly]
Added additional optional arguments and README guidance for storing
and accessing a Github personal access token (PAT) in the OSX
keychain
0.12.1 (2017-03-27)
-------------------
- Avoid remote branch name churn. [Chris Adams]
This avoids the backup output having lots of "[new branch]" messages
because removing the old remote name removed all of the existing branch
references.
- Fix detection of bare git directories. [Andrzej Maczuga]
0.12.0 (2016-11-22)
-------------------
Fix
~~~
- Properly import version from github_backup package. [Jose Diaz-
Gonzalez]
- Support alternate git status output. [Jose Diaz-Gonzalez]
Other
~~~~~
- Pep8: E501 line too long (83 > 79 characters) [Jose Diaz-Gonzalez]
- Pep8: E128 continuation line under-indented for visual indent. [Jose
Diaz-Gonzalez]
- Support archivization using bare git clones. [Andrzej Maczuga]
- Fix typo, 3x. [Terrell Russell]
0.11.0 (2016-10-26)
-------------------
- Support --token file:///home/user/token.txt (fixes gh-51) [Björn
Dahlgren]
- Fix some linting. [Albert Wang]
- Fix byte/string conversion for python 3. [Albert Wang]
- Support python 3. [Albert Wang]
- Encode special characters in password. [Remi Rampin]
- Don't pretend program name is "Github Backup" [Remi Rampin]
- Don't install over insecure connection. [Remi Rampin]
The git:// protocol is unauthenticated and unencrypted, and no longer advertised by GitHub. Using HTTPS shouldn't impact performance.
0.10.3 (2016-08-21)
-------------------
- Fixes #29. [Jonas Michel]
Reporting an error when the user's rate limit is exceeded causes
the script to terminate after resuming execution from a rate limit
sleep. Instead of generating an explicit error we just want to
inform the user that the script is going to sleep until their rate
limit count resets.
- Fixes #29. [Jonas Michel]
The errors list was not being cleared out after resuming a backup
from a rate limit sleep. When the backup was resumed, the non-empty
errors list caused the backup to quit after the next `retrieve_data`
request.
0.10.2 (2016-08-21)
-------------------
- Add a note regarding git version requirement. [Jose Diaz-Gonzalez]
Closes #37
0.10.0 (2016-08-18)
-------------------
- Implement incremental updates. [Robert Bradshaw]
Guarded with an --incremental flag.
Stores the time of the last update and only downloads issue and
pull request data since this time. All other data is relatively
small (likely fetched with a single request) and so is simply
re-populated from scratch as before.
0.9.0 (2016-03-29)
------------------
- Fix cloning private repos with basic auth or token. [Kazuki Suda]
0.8.0 (2016-02-14)
------------------
- Don't store issues which are actually pull requests. [Enrico Tröger]
This prevents storing pull requests twice since the Github API returns
@@ -19,43 +636,31 @@ Changelog
0.7.0 (2016-02-02)
------------------
- Softly fail if not able to read hooks. [Albert Wang]
- Add note about 2-factor auth. [Albert Wang]
- Make user repository search go through endpoint capable of reading
private repositories. [Albert Wang]
- Prompt for password if only username given. [Alex Hall]
0.6.0 (2015-11-10)
------------------
- Force proper remote url. [Jose Diaz-Gonzalez]
- Improve error handling in case of HTTP errors. [Enrico Tröger]
In case of a HTTP status code 404, the returned 'r' was never assigned.
In case of URL errors which are not timeouts, we probably should bail
out.
- Add --hooks to also include web hooks into the backup. [Enrico Tröger]
- Create the user specified output directory if it does not exist.
[Enrico Tröger]
Fixes #17.
- Add missing auth argument to _get_response() [Enrico Tröger]
When running unauthenticated and Github starts rate-limiting the client,
github-backup crashes because the used auth variable in _get_response()
was not available. This change should fix it.
- Add repository URL to error message for non-existing repositories.
[Enrico Tröger]
@@ -66,40 +671,28 @@ Changelog
0.5.0 (2015-10-10)
------------------
- Add release script. [Jose Diaz-Gonzalez]
- Refactor to both simplify codepath as well as follow PEP8 standards.
[Jose Diaz-Gonzalez]
- Retry 3 times when the connection times out. [Mathijs Jonker]
- Made unicode output defalut. [Kirill Grushetsky]
- Import alphabetised. [Kirill Grushetsky]
- Preserve Unicode characters in the output file. [Kirill Grushetsky]
Added option to preserve Unicode characters in the output file
- Josegonzales/python-github-backup#12 Added backup of labels and
milestones. [aensley]
- Fixed indent. [Mathijs Jonker]
- Skip unitialized repo's. [mjonker-embed]
These gave me errors which caused mails from crontab.
- Added prefer-ssh. [mjonker-embed]
Was needed for my back-up setup, code includes this but readme wasn't updated
- Retry API requests which failed due to rate-limiting. [Chris Adams]
This allows operation to continue, albeit at a slower pace,
if you have enough data to trigger the API rate limits
- Logging_subprocess: always log when a command fails. [Chris Adams]
Previously git clones could fail without any indication
@@ -109,21 +702,15 @@ Changelog
Now a non-zero return code will always output a message to
stderr and will display the executed command so it can be
rerun for troubleshooting.
- Switch to using ssh_url. [Chris Adams]
The previous commit used the wrong URL for a private repo. This was
masked by the lack of error loging in logging_subprocess (which will be
in a separate branch)
- Add an option to prefer checkouts over SSH. [Chris Adams]
This is really useful with private repos to avoid being nagged
for credentials for every repository
- Add pull request support. [Kevin Laude]
Back up reporitory pull requests by passing the --include-pulls
@@ -135,8 +722,6 @@ Changelog
Pull requests are automatically backed up when the --all argument is
uesd.
- Add GitHub Enterprise support. [Kevin Laude]
Pass the -H or --github-host argument with a GitHub Enterprise hostname
@@ -146,35 +731,21 @@ Changelog
0.2.0 (2014-09-22)
------------------
- Add support for retrieving repositories. Closes #1. [Jose Diaz-
Gonzalez]
- Fix PEP8 violations. [Jose Diaz-Gonzalez]
- Add authorization to header only if specified by user. [Ioannis
Filippidis]
- Fill out readme more. [Jose Diaz-Gonzalez]
- Fix import. [Jose Diaz-Gonzalez]
- Properly name readme. [Jose Diaz-Gonzalez]
- Create MANIFEST.in. [Jose Diaz-Gonzalez]
- Create .gitignore. [Jose Diaz-Gonzalez]
- Create setup.py. [Jose Diaz-Gonzalez]
- Create requirements.txt. [Jose Diaz-Gonzalez]
- Create __init__.py. [Jose Diaz-Gonzalez]
- Create LICENSE.txt. [Jose Diaz-Gonzalez]
- Create README.md. [Jose Diaz-Gonzalez]
- Create github-backup. [Jose Diaz-Gonzalez]

16
Dockerfile Normal file
View File

@@ -0,0 +1,16 @@
FROM python:3.9.18-slim
RUN --mount=type=cache,target=/var/cache/apt \
apt-get update && apt-get install -y git git-lfs
WORKDIR /usr/src/app
COPY release-requirements.txt .
RUN --mount=type=cache,target=/root/.cache/pip \
pip install -r release-requirements.txt
COPY . .
RUN --mount=type=cache,target=/root/.cache/pip \
pip install .
ENTRYPOINT [ "github-backup" ]

13
ISSUE_TEMPLATE.md Normal file
View File

@@ -0,0 +1,13 @@
# Important notice regarding filed issues
This project already fills my needs, and as such I have no real reason to continue it's development. This project is otherwise provided as is, and no support is given.
If pull requests implementing bug fixes or enhancements are pushed, I am happy to review and merge them (time permitting).
If you wish to have a bug fixed, you have a few options:
- Fix it yourself and file a pull request.
- File a bug and hope someone else fixes it for you.
- Pay me to fix it (my rate is $200 an hour, minimum 1 hour, contact me via my [github email address](https://github.com/josegonzalez) if you want to go this route).
In all cases, feel free to file an issue, they may be of help to others in the future.

7
PULL_REQUEST.md Normal file
View File

@@ -0,0 +1,7 @@
# Important notice regarding filed pull requests
This project already fills my needs, and as such I have no real reason to continue it's development. This project is otherwise provided as is, and no support is given.
I will attempt to review pull requests at _my_ earliest convenience. If I am unable to get to your pull request in a timely fashion, it is what it is. This repository does not pay any bills, and I am not required to merge any pull request from any individual.
If you wish to jump my personal priority queue, you may pay me for my time to review. My rate is $200 an hour - minimum 1 hour - feel free contact me via my github email address if you want to go this route.

View File

@@ -2,7 +2,15 @@
github-backup
=============
backup a github user or organization
|PyPI| |Python Versions|
The package can be used to backup an *entire* `Github <https://github.com/>`_ organization, repository or user account, including starred repos, issues and wikis in the most appropriate format (clones for wikis, json files for issues).
Requirements
============
- GIT 1.9+
- Python
Installation
============
@@ -11,23 +19,38 @@ Using PIP via PyPI::
pip install github-backup
Using PIP via Github::
Using PIP via Github (more likely the latest version)::
pip install git+git://github.com/josegonzalez/python-github-backup.git#egg=github-backup
pip install git+https://github.com/josegonzalez/python-github-backup.git#egg=github-backup
Usage
=====
*Install note for python newcomers:*
CLI Usage is as follows::
Python scripts are unlikely to be included in your ``$PATH`` by default, this means it cannot be run directly in terminal with ``$ github-backup ...``, you can either add python's install path to your environments ``$PATH`` or call the script directly e.g. using ``$ ~/.local/bin/github-backup``.*
Github Backup [-h] [-u USERNAME] [-p PASSWORD] [-t TOKEN]
[-o OUTPUT_DIRECTORY] [--starred] [--watched] [--all]
[--issues] [--issue-comments] [--issue-events] [--pulls]
[--pull-comments] [--pull-commits] [--labels] [--hooks]
[--milestones] [--repositories] [--wikis]
[--skip-existing] [-L [LANGUAGES [LANGUAGES ...]]]
Basic Help
==========
Show the CLI help output::
github-backup -h
CLI Help output::
github-backup [-h] [-u USERNAME] [-p PASSWORD] [-t TOKEN_CLASSIC]
[-f TOKEN_FINE] [--as-app] [-o OUTPUT_DIRECTORY]
[-l LOG_LEVEL] [-i] [--starred] [--all-starred]
[--watched] [--followers] [--following] [--all] [--issues]
[--issue-comments] [--issue-events] [--pulls]
[--pull-comments] [--pull-commits] [--pull-details]
[--labels] [--hooks] [--milestones] [--repositories]
[--bare] [--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]
[--keychain-account OSX_KEYCHAIN_ITEM_ACCOUNT]
[--releases] [--assets] [--exclude [REPOSITORY [REPOSITORY ...]]
[--throttle-limit THROTTLE_LIMIT] [--throttle-pause THROTTLE_PAUSE]
USER
Backup a github account
@@ -42,25 +65,43 @@ CLI Usage is as follows::
-p PASSWORD, --password PASSWORD
password for basic auth. If a username is given but
not a password, the password will be prompted for.
-t TOKEN, --token TOKEN
personal access or OAuth token
-f TOKEN_FINE, --token-fine TOKEN_FINE
fine-grained personal access token or path to token
(file://...)
-t TOKEN_CLASSIC, --token TOKEN_CLASSIC
personal access, OAuth, or JSON Web token, or path to
token (file://...)
--as-app authenticate as github app instead of as a user.
-o OUTPUT_DIRECTORY, --output-directory OUTPUT_DIRECTORY
directory at which to backup the repositories
--starred include starred repositories in backup
--watched include watched repositories in backup
--all include everything in backup
-l LOG_LEVEL, --log-level LOG_LEVEL
log level to use (default: info, possible levels:
debug, info, warning, error, critical)
-i, --incremental incremental backup
--starred include JSON output of starred repositories in backup
--all-starred include starred repositories in backup [*]
--watched include JSON output of watched repositories in backup
--followers include JSON output of followers in backup
--following include JSON output of following users in backup
--all include everything in backup (not including [*])
--issues include issues in backup
--issue-comments include issue comments in backup
--issue-events include issue events in backup
--pulls include pull requests in backup
--pull-comments include pull request review comments in backup
--pull-commits include pull request commits in backup
--pull-details include more pull request details in backup [*]
--labels include labels in backup
--hooks include hooks in backup (works only when
authenticated)
--milestones include milestones in backup
--repositories include repository clone in backup
--bare clone bare repositories
--lfs clone LFS repositories (requires Git LFS to be
installed, https://git-lfs.github.com) [*]
--wikis include wiki clone in backup
--gists include gists in backup [*]
--starred-gists include starred gists in backup [*]
--skip-existing skip project if a backup directory exists
-L [LANGUAGES [LANGUAGES ...]], --languages [LANGUAGES [LANGUAGES ...]]
only allow these languages
@@ -71,15 +112,218 @@ CLI Usage is as follows::
-O, --organization whether or not this is an organization user
-R REPOSITORY, --repository REPOSITORY
name of repository to limit backup to
-P, --private include private repositories
-F, --fork include forked repositories
-P, --private include private repositories [*]
-F, --fork include forked repositories [*]
--prefer-ssh Clone repositories using SSH instead of HTTPS
-v, --version show program's version number and exit
--keychain-name OSX_KEYCHAIN_ITEM_NAME
OSX ONLY: name field of password item in OSX keychain
that holds the personal access or OAuth token
--keychain-account OSX_KEYCHAIN_ITEM_ACCOUNT
OSX ONLY: account field of password item in OSX
keychain that holds the personal access or OAuth token
--releases include release information, not including assets or
binaries
--assets include assets alongside release information; only
applies if including releases
--exclude [REPOSITORY [REPOSITORY ...]]
names of repositories to exclude from backup.
--throttle-limit THROTTLE_LIMIT
start throttling of GitHub API requests after this
amount of API requests remain
--throttle-pause THROTTLE_PAUSE
wait this amount of seconds when API request
throttling is active (default: 30.0, requires
--throttle-limit to be set)
The package can be used to backup an *entire* organization or repository, including issues and wikis in the most appropriate format (clones for wikis, json files for issues).
Usage Details
=============
Authentication
==============
--------------
Note: Password-based authentication will fail if you have two-factor authentication enabled.
**Password-based authentication** will fail if you have two-factor authentication enabled, and will `be deprecated <https://github.blog/2023-03-09-raising-the-bar-for-software-security-github-2fa-begins-march-13/>`_ by 2023 EOY.
``--username`` is used for basic password authentication and separate from the positional argument ``USER``, which specifies the user account you wish to back up.
**Classic tokens** are `slightly less secure <https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#personal-access-tokens-classic>`_ as they provide very coarse-grained permissions.
If you need authentication for long-running backups (e.g. for a cron job) it is recommended to use **fine-grained personal access token** ``-f TOKEN_FINE``.
Fine Tokens
~~~~~~~~~~~
You can "generate new token", choosing the repository scope by selecting specific repos or all repos. On Github this is under *Settings -> Developer Settings -> Personal access tokens -> Fine-grained Tokens*
Customise the permissions for your use case, but for a personal account full backup you'll need to enable the following permissions:
**User permissions**: Read access to followers, starring, and watching.
**Repository permissions**: Read access to code, commit statuses, issues, metadata, pages, pull requests, and repository hooks.
Prefer SSH
~~~~~~~~~~
If cloning repos is enabled with ``--repositories``, ``--all-starred``, ``--wikis``, ``--gists``, ``--starred-gists`` using the ``--prefer-ssh`` argument will use ssh for cloning the git repos, but all other connections will still use their own protocol, e.g. API requests for issues uses HTTPS.
To clone with SSH, you'll need SSH authentication setup `as usual with Github <https://docs.github.com/en/authentication/connecting-to-github-with-ssh>`_, e.g. via SSH public and private keys.
Using the Keychain on Mac OSX
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Note: On Mac OSX the token can be stored securely in the user's keychain. To do this:
1. Open Keychain from "Applications -> Utilities -> Keychain Access"
2. Add a new password item using "File -> New Password Item"
3. Enter a name in the "Keychain Item Name" box. You must provide this name to github-backup using the --keychain-name argument.
4. Enter an account name in the "Account Name" box, enter your Github username as set above. You must provide this name to github-backup using the --keychain-account argument.
5. Enter your Github personal access token in the "Password" box
Note: When you run github-backup, you will be asked whether you want to allow "security" to use your confidential information stored in your keychain. You have two options:
1. **Allow:** In this case you will need to click "Allow" each time you run `github-backup`
2. **Always Allow:** In this case, you will not be asked for permission when you run `github-backup` in future. This is less secure, but is required if you want to schedule `github-backup` to run automatically
Github Rate-limit and Throttling
--------------------------------
"github-backup" will automatically throttle itself based on feedback from the Github API.
Their API is usually rate-limited to 5000 calls per hour. The API will ask github-backup to pause until a specific time when the limit is reset again (at the start of the next hour). This continues until the backup is complete.
During a large backup, such as ``--all-starred``, and on a fast connection this can result in (~20 min) pauses with bursts of API calls periodically maxing out the API limit. If this is not suitable `it has been observed <https://github.com/josegonzalez/python-github-backup/issues/76#issuecomment-636158717>`_ under real-world conditions that overriding the throttle with ``--throttle-limit 5000 --throttle-pause 0.6`` provides a smooth rate across the hour, although a ``--throttle-pause 0.72`` (3600 seconds [1 hour] / 5000 limit) is theoretically safer to prevent large rate-limit pauses.
About Git LFS
-------------
When you use the ``--lfs`` option, you will need to make sure you have Git LFS installed.
Instructions on how to do this can be found on https://git-lfs.github.com.
Gotchas / Known-issues
======================
All is not everything
---------------------
The ``--all`` argument does not include; cloning private repos (``-P, --private``), cloning forks (``-F, --fork``) cloning starred repositories (``--all-starred``), ``--pull-details``, cloning LFS repositories (``--lfs``), cloning gists (``--starred-gists``) or cloning starred gist repos (``--starred-gists``). See examples for more.
Cloning all starred size
------------------------
Using the ``--all-starred`` argument to clone all starred repositories may use a large amount of storage space, especially if ``--all`` or more arguments are used. e.g. commonly starred repos can have tens of thousands of issues, many large assets and the repo itself etc. Consider just storing links to starred repos in JSON format with ``--starred``.
Incremental Backup
------------------
Using (``-i, --incremental``) will only request new data from the API **since the last run (successful or not)**. e.g. only request issues from the API since the last run.
This means any blocking errors on previous runs can cause a large amount of missing data in backups.
Known blocking errors
---------------------
Some errors will block the backup run by exiting the script. e.g. receiving a 403 Forbidden error from the Github API.
If the incremental argument is used, this will result in the next backup only requesting API data since the last blocked/failed run. Potentially causing unexpected large amounts of missing data.
It's therefore recommended to only use the incremental argument if the output/result is being actively monitored, or complimented with periodic full non-incremental runs, to avoid unexpected missing data in a regular backup runs.
1. **Starred public repo hooks blocking**
Since the ``--all`` argument includes ``--hooks``, if you use ``--all`` and ``--all-starred`` together to clone a users starred public repositories, the backup will likely error and block the backup continuing.
This is due to needing the correct permission for ``--hooks`` on public repos.
2. **Releases blocking**
A known ``--releases`` (required for ``--assets``) error will sometimes block the backup.
If you're backing up a lot of repositories with releases e.g. an organisation or ``--all-starred``. You may need to remove ``--releases`` (and therefore ``--assets``) to complete a backup. Documented in `issue 209 <https://github.com/josegonzalez/python-github-backup/issues/209>`_.
"bare" is actually "mirror"
---------------------------
Using the bare clone argument (``--bare``) will actually call git's ``clone --mirror`` command. There's a subtle difference between `bare <https://www.git-scm.com/docs/git-clone#Documentation/git-clone.txt---bare>`_ and `mirror <https://www.git-scm.com/docs/git-clone#Documentation/git-clone.txt---mirror>`_ clone.
*From git docs "Compared to --bare, --mirror not only maps local branches of the source to local branches of the target, it maps all refs (including remote-tracking branches, notes etc.) and sets up a refspec configuration such that all these refs are overwritten by a git remote update in the target repository."*
Starred gists vs starred repo behaviour
---------------------------------------
The starred normal repo cloning (``--all-starred``) argument stores starred repos separately to the users own repositories. However, using ``--starred-gists`` will store starred gists within the same directory as the users own gists ``--gists``. Also, all gist repo directory names are IDs not the gist's name.
Skip existing on incomplete backups
-----------------------------------
The ``--skip-existing`` argument will skip a backup if the directory already exists, even if the backup in that directory failed (perhaps due to a blocking error). This may result in unexpected missing data in a regular backup.
Github Backup Examples
======================
Backup all repositories, including private ones using a classic token::
export ACCESS_TOKEN=SOME-GITHUB-TOKEN
github-backup WhiteHouse --token $ACCESS_TOKEN --organization --output-directory /tmp/white-house --repositories --private
Use a fine-grained access token to backup a single organization repository with everything else (wiki, pull requests, comments, issues etc)::
export FINE_ACCESS_TOKEN=SOME-GITHUB-TOKEN
ORGANIZATION=docker
REPO=cli
# e.g. git@github.com:docker/cli.git
github-backup $ORGANIZATION -P -f $FINE_ACCESS_TOKEN -o . --all -O -R $REPO
Quietly and incrementally backup useful Github user data (public and private repos with SSH) including; all issues, pulls, all public starred repos and gists (omitting "hooks", "releases" and therefore "assets" to prevent blocking). *Great for a cron job.* ::
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 --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. ::
export FINE_ACCESS_TOKEN=SOME-GITHUB-TOKEN
GH_USER=YOUR-GITHUB-USER
github-backup -f $FINE_ACCESS_TOKEN -o /tmp/github-backup/ -l debug -P --all-starred --starred --watched --followers --following --issues --issue-comments --issue-events --pulls --pull-comments --pull-commits --labels --milestones --repositories --wikis --releases --assets --pull-details --gists --starred-gists $GH_USER
Development
===========
This project is considered feature complete for the primary maintainer @josegonzalez. If you would like a bugfix or enhancement, pull requests are welcome. Feel free to contact the maintainer for consulting estimates if you'd like to sponsor the work instead.
Contibuters
-----------
A huge thanks to all the contibuters!
.. image:: https://contrib.rocks/image?repo=josegonzalez/python-github-backup
:target: https://github.com/josegonzalez/python-github-backup/graphs/contributors
:alt: contributors
Testing
-------
This project currently contains no unit tests. To run linting::
pip install flake8
flake8 --ignore=E501
.. |PyPI| image:: https://img.shields.io/pypi/v/github-backup.svg
:target: https://pypi.python.org/pypi/github-backup/
.. |Python Versions| image:: https://img.shields.io/pypi/pyversions/github-backup.svg
:target: https://github.com/josegonzalez/python-github-backup

View File

@@ -1,744 +1,60 @@
#!/usr/bin/env python
from __future__ import print_function
import os, sys, logging
import argparse
import base64
import calendar
import codecs
import errno
import getpass
import json
import logging
import os
import re
import select
import subprocess
import sys
import time
import urlparse
import urllib
import urllib2
logging.basicConfig(
format='%(asctime)s.%(msecs)03d: %(message)s',
datefmt='%Y-%m-%dT%H:%M:%S',
level=logging.INFO
)
from github_backup import __version__
FNULL = open(os.devnull, 'w')
def log_error(message):
if type(message) == str:
message = [message]
for msg in message:
sys.stderr.write("{0}\n".format(msg))
sys.exit(1)
def log_info(message):
if type(message) == str:
message = [message]
for msg in message:
sys.stdout.write("{0}\n".format(msg))
def logging_subprocess(popenargs,
from github_backup.github_backup import (
backup_account,
backup_repositories,
check_git_lfs_install,
filter_repositories,
get_authenticated_user,
logger,
stdout_log_level=logging.DEBUG,
stderr_log_level=logging.ERROR,
**kwargs):
"""
Variant of subprocess.call that accepts a logger instead of stdout/stderr,
and logs stdout messages via logger.debug and stderr messages via
logger.error.
"""
child = subprocess.Popen(popenargs, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, **kwargs)
log_level = {child.stdout: stdout_log_level,
child.stderr: stderr_log_level}
def check_io():
ready_to_read = select.select([child.stdout, child.stderr],
[],
[],
1000)[0]
for io in ready_to_read:
line = io.readline()
if not logger:
continue
if not (io == child.stderr and not line):
logger.log(log_level[io], line[:-1])
# keep checking stdout/stderr until the child exits
while child.poll() is None:
check_io()
check_io() # check again to catch anything after the process exits
rc = child.wait()
if rc != 0:
print(u'{} returned {}:'.format(popenargs[0], rc), file=sys.stderr)
print('\t', u' '.join(popenargs), file=sys.stderr)
return rc
def mkdir_p(*args):
for path in args:
try:
os.makedirs(path)
except OSError as exc: # Python >2.5
if exc.errno == errno.EEXIST and os.path.isdir(path):
pass
else:
raise
def mask_password(url, secret='*****'):
parsed = urlparse.urlparse(url)
if not parsed.password:
return url
elif parsed.password == 'x-oauth-basic':
return url.replace(parsed.username, secret)
return url.replace(parsed.password, secret)
def parse_args():
parser = argparse.ArgumentParser(description='Backup a github account',
prog='Github Backup')
parser.add_argument('user',
metavar='USER',
type=str,
help='github username')
parser.add_argument('-u',
'--username',
dest='username',
help='username for basic auth')
parser.add_argument('-p',
'--password',
dest='password',
help='password for basic auth. '
'If a username is given but not a password, the '
'password will be prompted for.')
parser.add_argument('-t',
'--token',
dest='token',
help='personal access or OAuth token')
parser.add_argument('-o',
'--output-directory',
default='.',
dest='output_directory',
help='directory at which to backup the repositories')
parser.add_argument('--starred',
action='store_true',
dest='include_starred',
help='include starred repositories in backup')
parser.add_argument('--watched',
action='store_true',
dest='include_watched',
help='include watched repositories in backup')
parser.add_argument('--all',
action='store_true',
dest='include_everything',
help='include everything in backup')
parser.add_argument('--issues',
action='store_true',
dest='include_issues',
help='include issues in backup')
parser.add_argument('--issue-comments',
action='store_true',
dest='include_issue_comments',
help='include issue comments in backup')
parser.add_argument('--issue-events',
action='store_true',
dest='include_issue_events',
help='include issue events in backup')
parser.add_argument('--pulls',
action='store_true',
dest='include_pulls',
help='include pull requests in backup')
parser.add_argument('--pull-comments',
action='store_true',
dest='include_pull_comments',
help='include pull request review comments in backup')
parser.add_argument('--pull-commits',
action='store_true',
dest='include_pull_commits',
help='include pull request commits in backup')
parser.add_argument('--labels',
action='store_true',
dest='include_labels',
help='include labels in backup')
parser.add_argument('--hooks',
action='store_true',
dest='include_hooks',
help='include hooks in backup (works only when authenticated)')
parser.add_argument('--milestones',
action='store_true',
dest='include_milestones',
help='include milestones in backup')
parser.add_argument('--repositories',
action='store_true',
dest='include_repository',
help='include repository clone in backup')
parser.add_argument('--wikis',
action='store_true',
dest='include_wiki',
help='include wiki clone in backup')
parser.add_argument('--skip-existing',
action='store_true',
dest='skip_existing',
help='skip project if a backup directory exists')
parser.add_argument('-L',
'--languages',
dest='languages',
help='only allow these languages',
nargs='*')
parser.add_argument('-N',
'--name-regex',
dest='name_regex',
help='python regex to match names against')
parser.add_argument('-H',
'--github-host',
dest='github_host',
help='GitHub Enterprise hostname')
parser.add_argument('-O',
'--organization',
action='store_true',
dest='organization',
help='whether or not this is an organization user')
parser.add_argument('-R',
'--repository',
dest='repository',
help='name of repository to limit backup to')
parser.add_argument('-P', '--private',
action='store_true',
dest='private',
help='include private repositories')
parser.add_argument('-F', '--fork',
action='store_true',
dest='fork',
help='include forked repositories')
parser.add_argument('--prefer-ssh',
action='store_true',
help='Clone repositories using SSH instead of HTTPS')
parser.add_argument('-v', '--version',
action='version',
version='%(prog)s ' + __version__)
return parser.parse_args()
def get_auth(args, encode=True):
auth = None
if args.token:
auth = args.token + ':' + 'x-oauth-basic'
elif args.username:
if not args.password:
args.password = getpass.getpass()
auth = args.username + ':' + args.password
elif args.password:
log_error('You must specify a username for basic auth')
if not auth:
return None
if encode == False:
return auth
return base64.b64encode(auth)
def get_github_api_host(args):
if args.github_host:
host = args.github_host + '/api/v3'
else:
host = 'api.github.com'
return host
def get_github_host(args):
if args.github_host:
host = args.github_host
else:
host = 'github.com'
return host
def get_github_repo_url(args, repository):
if args.prefer_ssh:
return repository['ssh_url']
auth = get_auth(args, False)
if auth:
repo_url = 'https://{0}@{1}/{2}/{3}.git'.format(
auth,
get_github_host(args),
args.user,
repository['name'])
else:
repo_url = repository['clone_url']
return repo_url
def retrieve_data(args, template, query_args=None, single_request=False):
auth = get_auth(args)
query_args = get_query_args(query_args)
per_page = 100
page = 0
data = []
while True:
page = page + 1
request = _construct_request(per_page, page, query_args, template, auth) # noqa
r, errors = _get_response(request, auth, template)
status_code = int(r.getcode())
if status_code != 200:
template = 'API request returned HTTP {0}: {1}'
errors.append(template.format(status_code, r.reason))
log_error(errors)
response = json.loads(r.read())
if len(errors) == 0:
if type(response) == list:
data.extend(response)
if len(response) < per_page:
break
elif type(response) == dict and single_request:
data.append(response)
if len(errors) > 0:
log_error(errors)
if single_request:
break
return data
def get_query_args(query_args=None):
if not query_args:
query_args = {}
return query_args
def _get_response(request, auth, template):
retry_timeout = 3
errors = []
# We'll make requests in a loop so we can
# delay and retry in the case of rate-limiting
while True:
should_continue = False
try:
r = urllib2.urlopen(request)
except urllib2.HTTPError as exc:
errors, should_continue = _request_http_error(exc, auth, errors) # noqa
r = exc
except urllib2.URLError:
should_continue = _request_url_error(template, retry_timeout)
if not should_continue:
raise
if should_continue:
continue
break
return r, errors
def _construct_request(per_page, page, query_args, template, auth):
querystring = urllib.urlencode(dict({
'per_page': per_page,
'page': page
}.items() + query_args.items()))
request = urllib2.Request(template + '?' + querystring)
if auth is not None:
request.add_header('Authorization', 'Basic ' + auth)
return request
def _request_http_error(exc, auth, errors):
# HTTPError behaves like a Response so we can
# check the status code and headers to see exactly
# what failed.
should_continue = False
headers = exc.headers
limit_remaining = int(headers.get('x-ratelimit-remaining', 0))
if exc.code == 403 and limit_remaining < 1:
# The X-RateLimit-Reset header includes a
# timestamp telling us when the limit will reset
# so we can calculate how long to wait rather
# than inefficiently polling:
gm_now = calendar.timegm(time.gmtime())
reset = int(headers.get('x-ratelimit-reset', 0)) or gm_now
# We'll never sleep for less than 10 seconds:
delta = max(10, reset - gm_now)
limit = headers.get('x-ratelimit-limit')
print('Exceeded rate limit of {} requests; waiting {} seconds to reset'.format(limit, delta), # noqa
file=sys.stderr)
ratelimit_error = 'No more requests remaining'
if auth is None:
ratelimit_error += '; authenticate to raise your GitHub rate limit' # noqa
errors.append(ratelimit_error)
time.sleep(delta)
should_continue = True
return errors, should_continue
def _request_url_error(template, retry_timeout):
# Incase of a connection timing out, we can retry a few time
# But we won't crash and not back-up the rest now
log_info('{} timed out'.format(template))
retry_timeout -= 1
if retry_timeout >= 0:
return True
log_error('{} timed out to much, skipping!')
return False
def retrieve_repositories(args):
log_info('Retrieving repositories')
single_request = False
template = 'https://{0}/user/repos'.format(
get_github_api_host(args))
if args.organization:
template = 'https://{0}/orgs/{1}/repos'.format(
get_github_api_host(args),
args.user)
if args.repository:
single_request = True
template = 'https://{0}/repos/{1}/{2}'.format(
get_github_api_host(args),
args.user,
args.repository)
return retrieve_data(args, template, single_request=single_request)
def filter_repositories(args, repositories):
log_info('Filtering repositories')
repositories = [r for r in repositories if r['owner']['login'] == args.user]
name_regex = None
if args.name_regex:
name_regex = re.compile(args.name_regex)
languages = None
if args.languages:
languages = [x.lower() for x in args.languages]
if not args.fork:
repositories = [r for r in repositories if not r['fork']]
if not args.private:
repositories = [r for r in repositories if not r['private']]
if languages:
repositories = [r for r in repositories if r['language'] and r['language'].lower() in languages] # noqa
if name_regex:
repositories = [r for r in repositories if name_regex.match(r['name'])]
return repositories
def backup_repositories(args, output_directory, repositories):
log_info('Backing up repositories')
repos_template = 'https://{0}/repos'.format(get_github_api_host(args))
for repository in repositories:
backup_cwd = os.path.join(output_directory, 'repositories')
repo_cwd = os.path.join(backup_cwd, repository['name'])
repo_dir = os.path.join(repo_cwd, 'repository')
repo_url = get_github_repo_url(args, repository)
if args.include_repository or args.include_everything:
fetch_repository(repository['name'],
repo_url,
repo_dir,
skip_existing=args.skip_existing)
download_wiki = (args.include_wiki or args.include_everything)
if repository['has_wiki'] and download_wiki:
fetch_repository(repository['name'],
repo_url.replace('.git', '.wiki.git'),
os.path.join(repo_cwd, 'wiki'),
skip_existing=args.skip_existing)
if args.include_issues or args.include_everything:
backup_issues(args, repo_cwd, repository, repos_template)
if args.include_pulls or args.include_everything:
backup_pulls(args, repo_cwd, repository, repos_template)
if args.include_milestones or args.include_everything:
backup_milestones(args, repo_cwd, repository, repos_template)
if args.include_labels or args.include_everything:
backup_labels(args, repo_cwd, repository, repos_template)
if args.include_hooks or args.include_everything:
backup_hooks(args, repo_cwd, repository, repos_template)
def backup_issues(args, repo_cwd, repository, repos_template):
has_issues_dir = os.path.isdir('{0}/issues/.git'.format(repo_cwd))
if args.skip_existing and has_issues_dir:
return
log_info('Retrieving {0} issues'.format(repository['full_name']))
issue_cwd = os.path.join(repo_cwd, 'issues')
mkdir_p(repo_cwd, issue_cwd)
issues = {}
issues_skipped = 0
issues_skipped_message = ''
_issue_template = '{0}/{1}/issues'.format(repos_template,
repository['full_name'])
issue_states = ['open', 'closed']
for issue_state in issue_states:
query_args = {
'filter': 'all',
'state': issue_state
}
_issues = retrieve_data(args,
_issue_template,
query_args=query_args)
for issue in _issues:
# skip pull requests which are also returned as issues
# if retrieving pull requests is requested as well
if 'pull_request' in issue and (args.include_pulls or args.include_everything):
issues_skipped += 1
continue
issues[issue['number']] = issue
if issues_skipped:
issues_skipped_message = ' (skipped {0} pull requests)'.format(issues_skipped)
log_info('Saving {0} issues to disk{1}'.format(len(issues.keys()), issues_skipped_message))
comments_template = _issue_template + '/{0}/comments'
events_template = _issue_template + '/{0}/events'
for number, issue in issues.iteritems():
if args.include_issue_comments or args.include_everything:
template = comments_template.format(number)
issues[number]['comment_data'] = retrieve_data(args, template)
if args.include_issue_events or args.include_everything:
template = events_template.format(number)
issues[number]['event_data'] = retrieve_data(args, template)
issue_file = '{0}/{1}.json'.format(issue_cwd, number)
with codecs.open(issue_file, 'w', encoding='utf-8') as f:
json_dump(issue, f)
def backup_pulls(args, repo_cwd, repository, repos_template):
has_pulls_dir = os.path.isdir('{0}/pulls/.git'.format(repo_cwd))
if args.skip_existing and has_pulls_dir:
return
log_info('Retrieving {0} pull requests'.format(repository['full_name'])) # noqa
pulls_cwd = os.path.join(repo_cwd, 'pulls')
mkdir_p(repo_cwd, pulls_cwd)
pulls = {}
_pulls_template = '{0}/{1}/pulls'.format(repos_template,
repository['full_name'])
pull_states = ['open', 'closed']
for pull_state in pull_states:
query_args = {
'filter': 'all',
'state': pull_state
}
_pulls = retrieve_data(args,
_pulls_template,
query_args=query_args)
for pull in _pulls:
pulls[pull['number']] = pull
log_info('Saving {0} pull requests to disk'.format(len(pulls.keys())))
comments_template = _pulls_template + '/{0}/comments'
commits_template = _pulls_template + '/{0}/commits'
for number, pull in pulls.iteritems():
if args.include_pull_comments or args.include_everything:
template = comments_template.format(number)
pulls[number]['comment_data'] = retrieve_data(args, template)
if args.include_pull_commits or args.include_everything:
template = commits_template.format(number)
pulls[number]['commit_data'] = retrieve_data(args, template)
pull_file = '{0}/{1}.json'.format(pulls_cwd, number)
with codecs.open(pull_file, 'w', encoding='utf-8') as f:
json_dump(pull, f)
def backup_milestones(args, repo_cwd, repository, repos_template):
milestone_cwd = os.path.join(repo_cwd, 'milestones')
if args.skip_existing and os.path.isdir(milestone_cwd):
return
log_info('Retrieving {0} milestones'.format(repository['full_name']))
mkdir_p(repo_cwd, milestone_cwd)
template = '{0}/{1}/milestones'.format(repos_template,
repository['full_name'])
query_args = {
'state': 'all'
}
_milestones = retrieve_data(args, template, query_args=query_args)
milestones = {}
for milestone in _milestones:
milestones[milestone['number']] = milestone
log_info('Saving {0} milestones to disk'.format(len(milestones.keys())))
for number, milestone in milestones.iteritems():
milestone_file = '{0}/{1}.json'.format(milestone_cwd, number)
with codecs.open(milestone_file, 'w', encoding='utf-8') as f:
json_dump(milestone, f)
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)
template = '{0}/{1}/labels'.format(repos_template,
repository['full_name'])
_backup_data(args,
'labels',
template,
output_file,
label_cwd)
def backup_hooks(args, repo_cwd, repository, repos_template):
auth = get_auth(args)
if not auth:
log_info("Skipping hooks since no authentication provided")
return
hook_cwd = os.path.join(repo_cwd, 'hooks')
output_file = '{0}/hooks.json'.format(hook_cwd)
template = '{0}/{1}/hooks'.format(repos_template,
repository['full_name'])
try:
_backup_data(args,
'hooks',
template,
output_file,
hook_cwd)
except SystemExit:
log_info("Unable to read hooks, skipping")
def fetch_repository(name, remote_url, local_dir, skip_existing=False):
clone_exists = os.path.exists(os.path.join(local_dir, '.git'))
if clone_exists and skip_existing:
return
masked_remote_url = mask_password(remote_url)
initalized = subprocess.call('git ls-remote ' + remote_url,
stdout=FNULL,
stderr=FNULL,
shell=True)
if initalized == 128:
log_info("Skipping {0} ({1}) since it's not initalized".format(name, masked_remote_url))
return
if clone_exists:
log_info('Updating {0} in {1}'.format(name, local_dir))
git_command = ['git', 'remote', 'rm', 'origin']
logging_subprocess(git_command, None, cwd=local_dir)
git_command = ['git', 'remote', 'add', 'origin', remote_url]
logging_subprocess(git_command, None, cwd=local_dir)
git_command = ['git', 'fetch', '--all', '--tags', '--prune']
logging_subprocess(git_command, None, cwd=local_dir)
else:
log_info('Cloning {0} repository from {1} to {2}'.format(name,
masked_remote_url,
local_dir))
git_command = ['git', 'clone', remote_url, local_dir]
logging_subprocess(git_command, None)
def backup_account(args, output_directory):
account_cwd = os.path.join(output_directory, 'account')
if args.include_starred or args.include_everything:
output_file = '{0}/starred.json'.format(account_cwd)
template = "https://{0}/users/{1}/starred"
template = template.format(get_github_api_host(args), args.user)
_backup_data(args,
'starred repositories',
template,
output_file,
account_cwd)
if args.include_watched or args.include_everything:
output_file = '{0}/watched.json'.format(account_cwd)
template = "https://{0}/users/{1}/subscriptions"
template = template.format(get_github_api_host(args), args.user)
_backup_data(args,
'watched repositories',
template,
output_file,
account_cwd)
def _backup_data(args, name, template, output_file, output_directory):
skip_existing = args.skip_existing
if not skip_existing or not os.path.exists(output_file):
log_info('Retrieving {0} {1}'.format(args.user, name))
mkdir_p(output_directory)
data = retrieve_data(args, template)
log_info('Writing {0} {1} to disk'.format(len(data), name))
with codecs.open(output_file, 'w', encoding='utf-8') as f:
json_dump(data, f)
def json_dump(data, output_file):
json.dump(data,
output_file,
ensure_ascii=False,
sort_keys=True,
indent=4,
separators=(',', ': '))
mkdir_p,
parse_args,
retrieve_repositories,
)
def main():
args = parse_args()
if args.quiet:
logger.setLevel(logging.WARNING)
output_directory = os.path.realpath(args.output_directory)
if not os.path.isdir(output_directory):
log_info('Create output directory {0}'.format(output_directory))
logger.info('Create output directory {0}'.format(output_directory))
mkdir_p(output_directory)
log_info('Backing up user {0} to {1}'.format(args.user, output_directory))
if args.lfs_clone:
check_git_lfs_install()
repositories = retrieve_repositories(args)
if args.log_level:
log_level = logging.getLevelName(args.log_level.upper())
if isinstance(log_level, int):
logger.root.setLevel(log_level)
if not args.as_app:
logger.info('Backing up user {0} to {1}'.format(args.user, output_directory))
authenticated_user = get_authenticated_user(args)
else:
authenticated_user = {'login': None}
repositories = retrieve_repositories(args, authenticated_user)
repositories = filter_repositories(args, repositories)
backup_repositories(args, output_directory, repositories)
backup_account(args, output_directory)
if __name__ == '__main__':
try:
main()
except Exception as e:
logger.error(str(e))
sys.exit(1)

View File

@@ -1 +1 @@
__version__ = '0.9.0'
__version__ = "0.44.1"

File diff suppressed because it is too large Load Diff

75
release
View File

@@ -1,8 +1,14 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $RELEASE_TRACE ]] && set -x
set -eo pipefail
[[ $RELEASE_TRACE ]] && set -x
PACKAGE_NAME='github-backup'
INIT_PACKAGE_NAME='github_backup'
if [[ ! -f setup.py ]]; then
echo -e "${RED}WARNING: Missing setup.py${COLOR_OFF}\n"
exit 1
fi
PACKAGE_NAME="$(cat setup.py | grep 'name="' | head | cut -d '"' -f2)"
INIT_PACKAGE_NAME="$(echo "${PACKAGE_NAME//-/_}")"
PUBLIC="true"
# Colors
@@ -14,18 +20,23 @@ MAGENTA="\033[0;35m" # magenta
CYAN="\033[0;36m" # cyan
# ensure wheel is available
pip install wheel > /dev/null
pip install wheel >/dev/null
command -v gitchangelog >/dev/null 2>&1 || {
echo -e "${RED}WARNING: Missing gitchangelog binary, please run: pip install gitchangelog==2.2.0${COLOR_OFF}\n"
echo -e "${RED}WARNING: Missing gitchangelog binary, please run: pip install gitchangelog==3.0.4${COLOR_OFF}\n"
exit 1
}
command -v rst-lint > /dev/null || {
command -v rst-lint >/dev/null || {
echo -e "${RED}WARNING: Missing rst-lint binary, please run: pip install restructuredtext_lint${COLOR_OFF}\n"
exit 1
}
command -v twine >/dev/null || {
echo -e "${RED}WARNING: Missing twine binary, please run: pip install twine==3.2.0${COLOR_OFF}\n"
exit 1
}
if [[ "$@" != "major" ]] && [[ "$@" != "minor" ]] && [[ "$@" != "patch" ]]; then
echo -e "${RED}WARNING: Invalid release type, must specify 'major', 'minor', or 'patch'${COLOR_OFF}\n"
exit 1
@@ -33,33 +44,33 @@ fi
echo -e "\n${GREEN}STARTING RELEASE PROCESS${COLOR_OFF}\n"
set +e;
git status | grep "working directory clean" &> /dev/null
set +e
git status | grep -Eo "working (directory|tree) clean" &>/dev/null
if [ ! $? -eq 0 ]; then # working directory is NOT clean
echo -e "${RED}WARNING: You have uncomitted changes, you may have forgotten something${COLOR_OFF}\n"
exit 1
fi
set -e;
set -e
echo -e "${YELLOW}--->${COLOR_OFF} Updating local copy"
git pull -q origin master
echo -e "${YELLOW}--->${COLOR_OFF} Retrieving release versions"
current_version=$(cat ${INIT_PACKAGE_NAME}/__init__.py |grep '__version__ ='|sed 's/[^0-9.]//g')
current_version=$(cat ${INIT_PACKAGE_NAME}/__init__.py | grep '__version__ =' | sed 's/[^0-9.]//g')
major=$(echo $current_version | awk '{split($0,a,"."); print a[1]}')
minor=$(echo $current_version | awk '{split($0,a,"."); print a[2]}')
patch=$(echo $current_version | awk '{split($0,a,"."); print a[3]}')
if [[ "$@" == "major" ]]; then
major=$(($major + 1));
major=$(($major + 1))
minor="0"
patch="0"
elif [[ "$@" == "minor" ]]; then
minor=$(($minor + 1));
minor=$(($minor + 1))
patch="0"
elif [[ "$@" == "patch" ]]; then
patch=$(($patch + 1));
patch=$(($patch + 1))
fi
next_version="${major}.${minor}.${patch}"
@@ -67,7 +78,7 @@ next_version="${major}.${minor}.${patch}"
echo -e "${YELLOW} >${COLOR_OFF} ${MAGENTA}${current_version}${COLOR_OFF} -> ${MAGENTA}${next_version}${COLOR_OFF}"
echo -e "${YELLOW}--->${COLOR_OFF} Ensuring readme passes lint checks (if this fails, run rst-lint)"
rst-lint README.rst > /dev/null
rst-lint README.rst || exit 1
echo -e "${YELLOW}--->${COLOR_OFF} Creating necessary temp file"
tempfoo=$(basename $0)
@@ -76,33 +87,29 @@ TMPFILE=$(mktemp /tmp/${tempfoo}.XXXXXX) || {
exit 1
}
find_this="__version__ = '$current_version'"
replace_with="__version__ = '$next_version'"
find_this="__version__ = \"$current_version\""
replace_with="__version__ = \"$next_version\""
echo -e "${YELLOW}--->${COLOR_OFF} Updating ${INIT_PACKAGE_NAME}/__init__.py"
sed "s/$find_this/$replace_with/" ${INIT_PACKAGE_NAME}/__init__.py > $TMPFILE && mv $TMPFILE ${INIT_PACKAGE_NAME}/__init__.py
find_this="${PACKAGE_NAME}.git@$current_version"
replace_with="${PACKAGE_NAME}.git@$next_version"
echo -e "${YELLOW}--->${COLOR_OFF} Updating README.rst"
sed "s/$find_this/$replace_with/" README.rst > $TMPFILE && mv $TMPFILE README.rst
sed "s/$find_this/$replace_with/" ${INIT_PACKAGE_NAME}/__init__.py >$TMPFILE && mv $TMPFILE ${INIT_PACKAGE_NAME}/__init__.py
if [ -f docs/conf.py ]; then
echo -e "${YELLOW}--->${COLOR_OFF} Updating docs"
find_this="version = '${current_version}'"
replace_with="version = '${next_version}'"
sed "s/$find_this/$replace_with/" docs/conf.py > $TMPFILE && mv $TMPFILE docs/conf.py
sed "s/$find_this/$replace_with/" docs/conf.py >$TMPFILE && mv $TMPFILE docs/conf.py
find_this="version = '${current_version}'"
replace_with="release = '${next_version}'"
sed "s/$find_this/$replace_with/" docs/conf.py > $TMPFILE && mv $TMPFILE docs/conf.py
sed "s/$find_this/$replace_with/" docs/conf.py >$TMPFILE && mv $TMPFILE docs/conf.py
fi
echo -e "${YELLOW}--->${COLOR_OFF} Updating CHANGES.rst for new release"
version_header="$next_version ($(date +%F))"
set +e; dashes=$(yes '-'|head -n ${#version_header}|tr -d '\n') ; set -e
gitchangelog |sed "4s/.*/$version_header/"|sed "5s/.*/$dashes/" > $TMPFILE && mv $TMPFILE CHANGES.rst
set +e
dashes=$(yes '-' | head -n ${#version_header} | tr -d '\n')
set -e
gitchangelog | sed "4s/.*/$version_header/" | sed "5s/.*/$dashes/" >$TMPFILE && mv $TMPFILE CHANGES.rst
echo -e "${YELLOW}--->${COLOR_OFF} Adding changed files to git"
git add CHANGES.rst README.rst ${INIT_PACKAGE_NAME}/__init__.py
@@ -111,6 +118,15 @@ if [ -f docs/conf.py ]; then git add docs/conf.py; fi
echo -e "${YELLOW}--->${COLOR_OFF} Creating release"
git commit -q -m "Release version $next_version"
if [[ "$PUBLIC" == "true" ]]; then
echo -e "${YELLOW}--->${COLOR_OFF} Creating python release files"
cp README.rst README
python setup.py sdist bdist_wheel >/dev/null
echo -e "${YELLOW}--->${COLOR_OFF} Validating long_description"
twine check dist/*
fi
echo -e "${YELLOW}--->${COLOR_OFF} Tagging release"
git tag -a $next_version -m "Release version $next_version"
@@ -118,9 +134,8 @@ echo -e "${YELLOW}--->${COLOR_OFF} Pushing release and tags to github"
git push -q origin master && git push -q --tags
if [[ "$PUBLIC" == "true" ]]; then
echo -e "${YELLOW}--->${COLOR_OFF} Creating python release"
cp README.rst README
python setup.py sdist bdist_wheel upload > /dev/null
echo -e "${YELLOW}--->${COLOR_OFF} Uploading python release"
twine upload dist/*
rm README
fi

38
release-requirements.txt Normal file
View File

@@ -0,0 +1,38 @@
autopep8==2.0.4
black==23.11.0
bleach==6.0.0
certifi==2023.7.22
charset-normalizer==3.1.0
click==8.1.7
colorama==0.4.6
docutils==0.20.1
flake8==6.1.0
gitchangelog==3.0.4
idna==3.4
importlib-metadata==6.6.0
jaraco.classes==3.2.3
keyring==23.13.1
markdown-it-py==2.2.0
mccabe==0.7.0
mdurl==0.1.2
more-itertools==9.1.0
mypy-extensions==1.0.0
packaging==23.2
pathspec==0.11.2
pkginfo==1.9.6
platformdirs==4.1.0
pycodestyle==2.11.1
pyflakes==3.1.0
Pygments==2.15.1
readme-renderer==37.3
requests==2.31.0
requests-toolbelt==1.0.0
restructuredtext-lint==1.4.0
rfc3986==2.0.0
rich==13.3.5
six==1.16.0
tqdm==4.65.0
twine==4.0.2
urllib3==2.0.7
webencodings==0.5.1
zipp==3.15.0

View File

@@ -5,6 +5,7 @@ from github_backup import __version__
try:
from setuptools import setup
setup # workaround for pyflakes issue #13
except ImportError:
from distutils.core import setup
@@ -15,6 +16,7 @@ except ImportError:
# http://www.eby-sarna.com/pipermail/peak/2010-May/003357.html)
try:
import multiprocessing
multiprocessing
except ImportError:
pass
@@ -25,23 +27,26 @@ def open_file(fname):
setup(
name='github-backup',
name="github-backup",
version=__version__,
author='Jose Diaz-Gonzalez',
author_email='github-backup@josediazgonzalez.com',
packages=['github_backup'],
scripts=['bin/github-backup'],
url='http://github.com/josegonzalez/python-github-backup',
license=open('LICENSE.txt').read(),
author="Jose Diaz-Gonzalez",
author_email="github-backup@josediazgonzalez.com",
packages=["github_backup"],
scripts=["bin/github-backup"],
url="http://github.com/josegonzalez/python-github-backup",
license="MIT",
classifiers=[
'Development Status :: 5 - Production/Stable',
'Topic :: System :: Archiving :: Backup',
'License :: OSI Approved :: MIT License',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
"Development Status :: 5 - Production/Stable",
"Topic :: System :: Archiving :: Backup",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
],
description='backup a github user or organization',
long_description=open_file('README.rst').read(),
install_requires=open_file('requirements.txt').readlines(),
description="backup a github user or organization",
long_description=open_file("README.rst").read(),
long_description_content_type="text/x-rst",
install_requires=open_file("requirements.txt").readlines(),
zip_safe=True,
)