├── .editorconfig ├── .github └── ISSUE_TEMPLATE.md ├── .gitignore ├── .readthedocs.yml ├── .travis.yml ├── AUTHORS.rst ├── CONTRIBUTING.rst ├── HISTORY.rst ├── LICENSE ├── MANIFEST.in ├── Makefile ├── README.rst ├── datakit_github ├── __init__.py ├── commands │ ├── __init__.py │ └── integrate.py ├── github_api.py ├── project_mixin.py └── repository.py ├── docs ├── Makefile ├── authors.rst ├── conf.py ├── contributing.rst ├── datakit_github.commands.rst ├── datakit_github.rst ├── history.rst ├── index.rst ├── install.rst ├── make.bat ├── modules.rst ├── readme.rst └── usage.rst ├── requirements-dev.txt ├── requirements.txt ├── setup.cfg ├── setup.py ├── tests ├── __init__.py ├── cassettes │ └── test_accounts.yaml ├── commands │ ├── __init__.py │ ├── cassettes │ │ ├── test_choose_default_account.yaml │ │ ├── test_choose_default_account_basic.yaml │ │ ├── test_choose_org_account_private_error.yaml │ │ ├── test_choose_org_account_public_repo.yaml │ │ ├── test_repo_already_exists.yaml │ │ ├── test_repo_already_exists_org_account.yaml │ │ ├── test_repo_already_initialized.yaml │ │ └── test_return_chosen_inputs.yaml │ ├── test_integrate.py │ └── test_integrate_basic.py ├── conftest.py ├── test_github_api.py └── test_repository.py └── tox.ini /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | indent_style = space 7 | indent_size = 4 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | charset = utf-8 11 | end_of_line = lf 12 | 13 | [*.bat] 14 | indent_style = tab 15 | end_of_line = crlf 16 | 17 | [LICENSE] 18 | insert_final_newline = false 19 | 20 | [Makefile] 21 | indent_style = tab 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * datakit-github version: 2 | * Python version: 3 | * Operating System: 4 | 5 | ### Description 6 | 7 | Describe what you were trying to get done. 8 | Tell us what happened, what went wrong, and what you expected to happen. 9 | 10 | ### What I Did 11 | 12 | ``` 13 | Paste the command(s) you ran and the output. 14 | If there was a crash, please include the traceback here. 15 | ``` 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | 55 | # Sphinx documentation 56 | docs/_build/ 57 | #docs/ 58 | #!docs/Makefile 59 | #!docs/authors.rst 60 | #!docs/contributing.rst 61 | #!docs/history.rst 62 | #!docs/index.rst 63 | #!docs/make.bat 64 | #!docs/readme.rst 65 | 66 | # Example Cliff command 67 | tests/test_greet.py 68 | datakit_github/greet.py 69 | 70 | # PyBuilder 71 | target/ 72 | 73 | # pyenv python configuration file 74 | .python-version 75 | -------------------------------------------------------------------------------- /.readthedocs.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | python: 3 | version: 3.7 4 | # Add a requirements.txt file if needed 5 | # install: 6 | # - requirements: requirements.txt 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # Config file for automatic testing at travis-ci.org 2 | # This file will be regenerated if you run travis_pypi_setup.py 3 | language: python 4 | matrix: 5 | include: 6 | - python: "3.5" 7 | env: TOXENV=py35 8 | - python: "3.6" 9 | env: TOXENV=py36 10 | - python: "3.7" 11 | env: TOXENV=py37 12 | - python: "3.8" 13 | env: TOXENV=py38 14 | - python: "3.9" 15 | env: TOXENV=py39 16 | 17 | # command to install dependencies, e.g. pip install -r requirements.txt --use-mirrors 18 | install: pip install -U tox 19 | 20 | # command to run tests, e.g. python setup.py test 21 | script: 22 | - tox 23 | 24 | 25 | -------------------------------------------------------------------------------- /AUTHORS.rst: -------------------------------------------------------------------------------- 1 | ======= 2 | Credits 3 | ======= 4 | 5 | Development Lead 6 | ---------------- 7 | 8 | * Serdar Tumgoren 9 | 10 | Contributors 11 | ------------ 12 | 13 | * Justin Myers 14 | 15 | * Larry Fenn -------------------------------------------------------------------------------- /CONTRIBUTING.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: shell 2 | 3 | ============ 4 | Contributing 5 | ============ 6 | 7 | Contributions are welcome, and they are greatly appreciated! Every 8 | little bit helps, and credit will always be given. 9 | 10 | You can contribute in many ways: 11 | 12 | Types of Contributions 13 | ---------------------- 14 | 15 | Report Bugs 16 | ~~~~~~~~~~~ 17 | 18 | Report bugs at https://github.com/associatedpress/datakit-github/issues. 19 | 20 | If you are reporting a bug, please include: 21 | 22 | * Your operating system name and version. 23 | * Any details about your local setup that might be helpful in troubleshooting. 24 | * Detailed steps to reproduce the bug. 25 | 26 | Fix Bugs 27 | ~~~~~~~~ 28 | 29 | Look through the GitHub issues for bugs. Anything tagged with "bug" 30 | and "help wanted" is open to whoever wants to implement it. 31 | 32 | Implement Features 33 | ~~~~~~~~~~~~~~~~~~ 34 | 35 | Look through the GitHub issues for features. Anything tagged with "enhancement" 36 | and "help wanted" is open to whoever wants to implement it. 37 | 38 | Write Documentation 39 | ~~~~~~~~~~~~~~~~~~~ 40 | 41 | datakit-github could always use more documentation, whether as part of the 42 | official datakit-github docs, in docstrings, or even on the web in blog posts, 43 | articles, and such. 44 | 45 | Submit Feedback 46 | ~~~~~~~~~~~~~~~ 47 | 48 | The best way to send feedback is to file an issue at https://github.com/associatedpress/datakit-github/issues. 49 | 50 | If you are proposing a feature: 51 | 52 | * Explain in detail how it would work. 53 | * Keep the scope as narrow as possible, to make it easier to implement. 54 | * Remember that this is a volunteer-driven project, and that contributions 55 | are welcome :) 56 | 57 | Get Started! 58 | ------------ 59 | 60 | Ready to contribute? Here's how to set up `datakit-github` for local development. 61 | 62 | 1. Fork the `datakit-github` repo on GitHub. 63 | 2. Clone your fork locally:: 64 | 65 | $ git clone git@github.com:your_name_here/datakit-github.git 66 | 67 | 3. Install your local copy into a virtualenv. Assuming you have virtualenvwrapper installed, this is how you set up your fork for local development:: 68 | 69 | $ mkvirtualenv datakit-github 70 | $ cd datakit-github/ 71 | $ python setup.py develop 72 | 73 | 4. Create a branch for local development:: 74 | 75 | $ git checkout -b name-of-your-bugfix-or-feature 76 | 77 | Now you can make your changes locally. 78 | 79 | 5. When you're done making changes, check that your changes pass flake8 and the tests, including testing other Python versions with tox:: 80 | 81 | $ flake8 datakit_github tests 82 | $ py.test 83 | $ tox 84 | 85 | To get flake8 and tox, just pip install them into your virtualenv. 86 | 87 | 6. Commit your changes and push your branch to GitHub:: 88 | 89 | $ git add . 90 | $ git commit -m "Your detailed description of your changes." 91 | $ git push origin name-of-your-bugfix-or-feature 92 | 93 | 7. Submit a pull request through the GitHub website. 94 | 95 | Pull Request Guidelines 96 | ----------------------- 97 | 98 | Before you submit a pull request, check that it meets these guidelines: 99 | 100 | 1. The pull request should include tests. 101 | 2. If the pull request adds functionality, the docs should be updated. Put 102 | your new functionality into a function with a docstring, and add the 103 | feature to the list in README.rst. 104 | 3. The pull request should work for Python version 3.3 or higher. Check 105 | https://travis-ci.org/associatedpress/datakit-github/pull_requests 106 | and make sure that the tests pass for all supported Python versions. 107 | -------------------------------------------------------------------------------- /HISTORY.rst: -------------------------------------------------------------------------------- 1 | ======= 2 | History 3 | ======= 4 | 5 | 0.2.1 (2022-12-06) 6 | ------------------ 7 | * Improve error messages for failed runs on empty projects 8 | 9 | 0.2.0 (2022-07-19) 10 | ------------------ 11 | * Update handling of "main" vs. "master" branch names to default "main" 12 | regardless of configured default 13 | 14 | 0.1.2 (2022-01-18) 15 | ------------------ 16 | * Bugfix update to use main (rather than master) as default branch to reflect 17 | GitHub's official update to this convention. 18 | 19 | 20 | 0.1.1 (2019-12-31) 21 | ------------------ 22 | * Update the Integrate command's take_action method to 23 | return the repo slug, selected GH account, and privacy selection. 24 | 25 | 26 | 0.1.0 (2019-10-04) 27 | ------------------ 28 | 29 | * Initial release containing the GitHub "integrate" command. 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | ISC License 3 | 4 | Copyright (c) 2019, Serdar Tumgoren 5 | 6 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 9 | 10 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | 2 | include AUTHORS.rst 3 | 4 | include CONTRIBUTING.rst 5 | include HISTORY.rst 6 | include LICENSE 7 | include README.rst 8 | 9 | recursive-include tests * 10 | recursive-exclude * __pycache__ 11 | recursive-exclude * *.py[co] 12 | 13 | recursive-include docs *.rst conf.py Makefile make.bat *.jpg *.png *.gif 14 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: clean clean-test clean-pyc clean-build docs help 2 | .DEFAULT_GOAL := help 3 | define BROWSER_PYSCRIPT 4 | import os, webbrowser, sys 5 | try: 6 | from urllib import pathname2url 7 | except: 8 | from urllib.request import pathname2url 9 | 10 | webbrowser.open("file://" + pathname2url(os.path.abspath(sys.argv[1]))) 11 | endef 12 | export BROWSER_PYSCRIPT 13 | 14 | define PRINT_HELP_PYSCRIPT 15 | import re, sys 16 | 17 | for line in sys.stdin: 18 | match = re.match(r'^([a-zA-Z_-]+):.*?## (.*)$$', line) 19 | if match: 20 | target, help = match.groups() 21 | print("%-20s %s" % (target, help)) 22 | endef 23 | export PRINT_HELP_PYSCRIPT 24 | BROWSER := python -c "$$BROWSER_PYSCRIPT" 25 | 26 | help: 27 | @python -c "$$PRINT_HELP_PYSCRIPT" < $(MAKEFILE_LIST) 28 | 29 | clean: clean-build clean-pyc clean-test ## remove all build, test, coverage and Python artifacts 30 | 31 | 32 | clean-build: ## remove build artifacts 33 | rm -fr build/ 34 | rm -fr dist/ 35 | rm -fr .eggs/ 36 | find . -name '*.egg-info' -exec rm -fr {} + 37 | find . -name '*.egg' -exec rm -f {} + 38 | 39 | clean-pyc: ## remove Python file artifacts 40 | find . -name '*.pyc' -exec rm -f {} + 41 | find . -name '*.pyo' -exec rm -f {} + 42 | find . -name '*~' -exec rm -f {} + 43 | find . -name '__pycache__' -exec rm -fr {} + 44 | 45 | clean-test: ## remove test and coverage artifacts 46 | rm -fr .tox/ 47 | rm -f .coverage 48 | rm -fr htmlcov/ 49 | 50 | lint: ## check style with flake8 51 | flake8 datakit_github tests 52 | 53 | test: ## run tests quickly with the default Python 54 | py.test 55 | 56 | test-all: ## run tests on every Python version with tox 57 | tox -p auto 58 | 59 | coverage: ## check code coverage quickly with the default Python 60 | coverage run --source datakit_github -m pytest 61 | coverage report -m 62 | coverage html 63 | $(BROWSER) htmlcov/index.html 64 | 65 | docs: ## generate Sphinx HTML documentation, including API docs 66 | rm -f docs/datakit_github.rst 67 | rm -f docs/modules.rst 68 | sphinx-apidoc -o docs/ datakit_github 69 | $(MAKE) -C docs clean 70 | $(MAKE) -C docs html 71 | $(BROWSER) docs/_build/html/index.html 72 | 73 | servedocs: docs ## compile the docs watching for changes 74 | watchmedo shell-command -p '*.rst' -c '$(MAKE) -C docs html' -R -D . 75 | 76 | check-release: ## check release for potential errors 77 | twine check dist/* 78 | 79 | test-release: clean dist ## release distros to test.pypi.org 80 | twine upload -r testpypi dist/* 81 | 82 | release: clean dist ## package and upload a release 83 | twine upload -r pypi dist/* 84 | 85 | dist: clean ## builds source and wheel package 86 | python setup.py sdist 87 | python setup.py bdist_wheel 88 | ls -l dist 89 | 90 | install: clean ## install the package to the active Python's site-packages 91 | python setup.py install 92 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | 2 | .. image:: https://img.shields.io/pypi/v/datakit-github.svg 3 | :target: https://pypi.python.org/pypi/datakit-github 4 | 5 | .. image:: https://img.shields.io/pypi/pyversions/datakit-github.svg 6 | :target: https://pypi.python.org/pypi/datakit-github 7 | 8 | .. image:: https://img.shields.io/travis/associatedpress/datakit-github.svg 9 | :target: https://travis-ci.org/associatedpress/datakit-github 10 | 11 | .. image:: https://readthedocs.org/projects/datakit-github/badge/?version=latest 12 | :target: https://datakit-github.readthedocs.io/en/latest/?badge=latest 13 | :alt: Documentation Status 14 | 15 | ===================== 16 | DataKit GitHub plugin 17 | ===================== 18 | 19 | Overview 20 | ======== 21 | 22 | This plugin provides light-weight GitHub integration for the DataKit_ command-line tool. 23 | It's designed to streamline the process of generating a GitHub project 24 | and linking it to a local directory containing a newly created project skeleton. 25 | It's intended to be used in tandem with the datakit-project_ plugin, which 26 | helps generate project skeletons for data work and software development. 27 | 28 | 29 | * Documentation: http://datakit-github.readthedocs.io/en/latest/ 30 | * GitHub: https://github.com/associatedpress/datakit-github 31 | * PyPI: https://pypi.python.org/pypi/datakit-github 32 | * Free and open source software: `ISC license`_ 33 | 34 | .. _ISC license: https://github.com/associatedpress/datakit-github/blob/master/LICENSE 35 | 36 | Features 37 | ======== 38 | 39 | 40 | The plugin provides the following features: 41 | 42 | * Interactive selection of GitHub account for project creation 43 | * Automated creation of a GitHub project 44 | * Ability to set privacy level of repo 45 | * Automated execution of git commands to bootstrap a project (init/add/commit) 46 | * Linking of local Git repository to newly created GitHub project 47 | * Automated "push" of initial commit to new GitHub project 48 | 49 | 50 | In action 51 | ========== 52 | 53 | Once datakit-github_ is installed, it becomes a cinch to "gitify" newly created 54 | projects and integrate them with GitHub:: 55 | 56 | # After generating an initial project structure... 57 | cd my-awesome-project 58 | 59 | # ...you can transform the project into a git repo 60 | # and integrate with GitHub with a single command 61 | datakit github integrate 62 | 63 | 64 | .. note:: Check out the :ref:`install` and :ref:`usage` docs for more details. 65 | 66 | 67 | .. _GitHub: https://github.com 68 | .. _datakit-github: https://github.com/associatedpress/datakit-github 69 | .. _DataKit: https://datakit.ap.org 70 | .. _datakit-github docs: https://datakit-github.readthedocs.io/en/latest/ 71 | .. _datakit-project: https://datakit-project.readthedocs.io/en/latest/ 72 | -------------------------------------------------------------------------------- /datakit_github/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | __author__ = """Serdar Tumgoren""" 4 | __email__ = 'zstumgoren@gmail.com' 5 | __version__ = '0.2.1' 6 | -------------------------------------------------------------------------------- /datakit_github/commands/__init__.py: -------------------------------------------------------------------------------- 1 | from datakit_github.commands.integrate import Integrate 2 | -------------------------------------------------------------------------------- /datakit_github/commands/integrate.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import os 3 | from cliff.command import Command 4 | from github.GithubException import GithubException 5 | from datakit_github.github_api import GithubApi 6 | from datakit_github.repository import Repository 7 | from datakit_github.project_mixin import ProjectMixin 8 | 9 | 10 | def ask(question): 11 | return input(question) 12 | 13 | 14 | class Integrate(ProjectMixin, Command): 15 | "Integrate local project code with Github" 16 | 17 | def take_action(self, parsed_args): 18 | if os.listdir() == ['.git'] or not bool(os.listdir()): 19 | msg = "ERROR: Project is empty, nothing to commit" 20 | self.log.info(msg) 21 | return 22 | # Check for Github API key from configs 23 | # TODO: Provide more helpful error message on how to create API key 24 | # and configure plugin locally 25 | api_key = self.configs.get('github_api_key') 26 | if not api_key: 27 | err_msg = "You must configure a Github API key to use this command!!\n" 28 | self.log.error(err_msg) 29 | elif Repository.initialized(): 30 | self.log.error("\nERROR: Repo has already been initialized locally!!") 31 | self.log.error( 32 | "You must either remove the .git/ directory " + 33 | "before re-running this command, or manually " + 34 | "configure Github integration.\n" 35 | ) 36 | else: 37 | account = self.choose_account(api_key) 38 | confirm = self.confirm_account_choice(account) 39 | if confirm in ["y", ""]: 40 | # TODO: Handle overrides for project settings from 41 | # configs and/or command-line flags (e.g. privacy) 42 | privacy_choice = ask("Should this repo be private? y/n [y]: ").strip().lower() 43 | privacy = True if privacy_choice in ['', 'y'] else False 44 | try: 45 | repo = account.create_repo(self.project_slug, private=privacy) 46 | self.log.info("Repo created at {}".format(repo.html_url)) 47 | self.run_local_git_commands(repo) 48 | except GithubException as err: 49 | try: 50 | error_msg = err.data['errors'][0]['message'] 51 | except KeyError: 52 | error_msg = err.data['message'] 53 | msg = "\nERROR: Failed to create {} for {}: {}!!\n".format( 54 | self.project_slug, 55 | account.login, 56 | error_msg 57 | ) 58 | self.log.error(msg) 59 | finally: 60 | return { 61 | 'account': account.login, 62 | 'repo_name': self.project_slug, 63 | 'private_repo': privacy 64 | } 65 | 66 | def choose_account(self, api_key): 67 | accounts = GithubApi.accounts(api_key) 68 | if len(accounts) == 1: 69 | target_account = accounts[0] 70 | else: 71 | msg = "Choose an account where the new project should be created:\n" 72 | account_lkup = {} 73 | self.log.info(msg) 74 | for idx, account in enumerate(accounts): 75 | num = idx + 1 76 | account_lkup[num] = account 77 | self.log.info("({}) {}".format(num, account.login)) 78 | # TODO: Check plugin for default account configuration, 79 | # otherwise default to personal account 80 | default = account_lkup[1] 81 | choice_msg = "\nType a number or leave blank for default [{}]: ".format(default.login) 82 | choice = ask(choice_msg) 83 | if choice.strip() == '': 84 | target_account = default 85 | else: 86 | target_account = account_lkup[int(choice)] 87 | return target_account 88 | 89 | def confirm_account_choice(self, target_account): 90 | self.log.info("Repo will be created on account: {}".format(target_account.login)) 91 | choice = ask("Is this correct? y/n [y]: ").strip().lower() 92 | return choice 93 | 94 | def run_local_git_commands(self, repo): 95 | self.log.info("Running local Git initialization...") 96 | # TODO: Create a project-level config/datakit-github.json? 97 | # containing name of selected account and possibly account type (org or user)? 98 | # This can be used downstream to configure org or user-specific API calls 99 | # if any (hold off on the "type" config until we 100 | # determine if there are different call ypes) 101 | Repository.init() 102 | Repository.add() 103 | Repository.commit("Initial commit") 104 | Repository.rename_current_branch("main") 105 | Repository.add_remote(repo.ssh_url) 106 | alert_msg = 'Local repo linked to remote origin: \n\t{}'.format(repo.html_url) 107 | self.log.info(alert_msg) 108 | Repository.push() 109 | self.log.info("First commit made locally and pushed to remote") 110 | self.log.info("View the project on Github at {}".format(repo.html_url)) 111 | -------------------------------------------------------------------------------- /datakit_github/github_api.py: -------------------------------------------------------------------------------- 1 | from operator import attrgetter 2 | from github import Github 3 | 4 | 5 | class GithubApi: 6 | 7 | @staticmethod 8 | def accounts(api_key): 9 | g = Github(api_key) 10 | user = g.get_user() 11 | accounts = [user] 12 | orgs = [org for org in user.get_orgs()] 13 | sorted_orgs = sorted(orgs, key=attrgetter('login')) 14 | accounts.extend(sorted_orgs) 15 | return accounts 16 | -------------------------------------------------------------------------------- /datakit_github/project_mixin.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import logging 3 | import os 4 | 5 | 6 | from datakit import CommandHelpers 7 | 8 | 9 | class ProjectMixin(CommandHelpers): 10 | 11 | "Mixin with code useful across plugin commands" 12 | 13 | plugin_slug = 'datakit-github' 14 | 15 | log = logging.getLogger(__name__) 16 | log.setLevel(logging.INFO) 17 | 18 | @property 19 | def project_slug(self): 20 | return os.path.basename(os.getcwd()) 21 | -------------------------------------------------------------------------------- /datakit_github/repository.py: -------------------------------------------------------------------------------- 1 | import os 2 | import subprocess 3 | 4 | 5 | class Repository: 6 | 7 | @staticmethod 8 | def initialized(): 9 | return os.path.exists('.git') 10 | 11 | @staticmethod 12 | def init(): 13 | return subprocess.check_output(['git', 'init']) 14 | 15 | @staticmethod 16 | def add(): 17 | return subprocess.check_output(['git', 'add', '.']) 18 | 19 | @staticmethod 20 | def commit(message): 21 | return subprocess.check_output(['git', 'commit', '-m', message]) 22 | 23 | @staticmethod 24 | def add_remote(repo_url, name='origin'): 25 | return subprocess.check_output(['git', 'remote', 'add', name, repo_url]) 26 | 27 | @staticmethod 28 | def rename_current_branch(new_name): 29 | return subprocess.check_output(['git', 'branch', '--move', new_name]) 30 | 31 | @staticmethod 32 | def push(remote='origin', branch='main'): 33 | return subprocess.check_output(['git', 'push', '-u', remote, branch]) 34 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = _build 9 | 10 | # User-friendly check for sphinx-build 11 | ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) 12 | $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) 13 | endif 14 | 15 | # Internal variables. 16 | PAPEROPT_a4 = -D latex_paper_size=a4 17 | PAPEROPT_letter = -D latex_paper_size=letter 18 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 19 | # the i18n builder cannot share the environment and doctrees with the others 20 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 21 | 22 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext 23 | 24 | help: 25 | @echo "Please use \`make ' where is one of" 26 | @echo " html to make standalone HTML files" 27 | @echo " dirhtml to make HTML files named index.html in directories" 28 | @echo " singlehtml to make a single large HTML file" 29 | @echo " pickle to make pickle files" 30 | @echo " json to make JSON files" 31 | @echo " htmlhelp to make HTML files and a HTML help project" 32 | @echo " qthelp to make HTML files and a qthelp project" 33 | @echo " devhelp to make HTML files and a Devhelp project" 34 | @echo " epub to make an epub" 35 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 36 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 37 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" 38 | @echo " text to make text files" 39 | @echo " man to make manual pages" 40 | @echo " texinfo to make Texinfo files" 41 | @echo " info to make Texinfo files and run them through makeinfo" 42 | @echo " gettext to make PO message catalogs" 43 | @echo " changes to make an overview of all changed/added/deprecated items" 44 | @echo " xml to make Docutils-native XML files" 45 | @echo " pseudoxml to make pseudoxml-XML files for display purposes" 46 | @echo " linkcheck to check all external links for integrity" 47 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 48 | 49 | clean: 50 | rm -rf $(BUILDDIR)/* 51 | 52 | html: 53 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 54 | @echo 55 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 56 | 57 | dirhtml: 58 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 59 | @echo 60 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 61 | 62 | singlehtml: 63 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 64 | @echo 65 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 66 | 67 | pickle: 68 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 69 | @echo 70 | @echo "Build finished; now you can process the pickle files." 71 | 72 | json: 73 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 74 | @echo 75 | @echo "Build finished; now you can process the JSON files." 76 | 77 | htmlhelp: 78 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 79 | @echo 80 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 81 | ".hhp project file in $(BUILDDIR)/htmlhelp." 82 | 83 | qthelp: 84 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 85 | @echo 86 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 87 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 88 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/datakit-github.qhcp" 89 | @echo "To view the help file:" 90 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/datakit-github.qhc" 91 | 92 | devhelp: 93 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 94 | @echo 95 | @echo "Build finished." 96 | @echo "To view the help file:" 97 | @echo "# mkdir -p $$HOME/.local/share/devhelp/datakit-github" 98 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/datakit-github" 99 | @echo "# devhelp" 100 | 101 | epub: 102 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 103 | @echo 104 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 105 | 106 | latex: 107 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 108 | @echo 109 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 110 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 111 | "(use \`make latexpdf' here to do that automatically)." 112 | 113 | latexpdf: 114 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 115 | @echo "Running LaTeX files through pdflatex..." 116 | $(MAKE) -C $(BUILDDIR)/latex all-pdf 117 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 118 | 119 | latexpdfja: 120 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 121 | @echo "Running LaTeX files through platex and dvipdfmx..." 122 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja 123 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 124 | 125 | text: 126 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 127 | @echo 128 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 129 | 130 | man: 131 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 132 | @echo 133 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 134 | 135 | texinfo: 136 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 137 | @echo 138 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." 139 | @echo "Run \`make' in that directory to run these through makeinfo" \ 140 | "(use \`make info' here to do that automatically)." 141 | 142 | info: 143 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 144 | @echo "Running Texinfo files through makeinfo..." 145 | make -C $(BUILDDIR)/texinfo info 146 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." 147 | 148 | gettext: 149 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale 150 | @echo 151 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." 152 | 153 | changes: 154 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 155 | @echo 156 | @echo "The overview file is in $(BUILDDIR)/changes." 157 | 158 | linkcheck: 159 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 160 | @echo 161 | @echo "Link check complete; look for any errors in the above output " \ 162 | "or in $(BUILDDIR)/linkcheck/output.txt." 163 | 164 | doctest: 165 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 166 | @echo "Testing of doctests in the sources finished, look at the " \ 167 | "results in $(BUILDDIR)/doctest/output.txt." 168 | 169 | xml: 170 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml 171 | @echo 172 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml." 173 | 174 | pseudoxml: 175 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml 176 | @echo 177 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." 178 | -------------------------------------------------------------------------------- /docs/authors.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../AUTHORS.rst 2 | -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # datakit-github documentation build configuration file, created by 5 | # sphinx-quickstart on Tue Jul 9 22:26:36 2013. 6 | # 7 | # This file is execfile()d with the current directory set to its 8 | # containing dir. 9 | # 10 | # Note that not all possible configuration values are present in this 11 | # autogenerated file. 12 | # 13 | # All configuration values have a default; values that are commented out 14 | # serve to show the default. 15 | 16 | import sys 17 | import os 18 | 19 | # If extensions (or modules to document with autodoc) are in another 20 | # directory, add these directories to sys.path here. If the directory is 21 | # relative to the documentation root, use os.path.abspath to make it 22 | # absolute, like shown here. 23 | #sys.path.insert(0, os.path.abspath('.')) 24 | 25 | # Get the project root dir, which is the parent dir of this 26 | cwd = os.getcwd() 27 | project_root = os.path.dirname(cwd) 28 | 29 | # Insert the project root dir as the first element in the PYTHONPATH. 30 | # This lets us ensure that the source package is imported, and that its 31 | # version is used. 32 | sys.path.insert(0, project_root) 33 | 34 | import datakit_github 35 | 36 | # -- General configuration --------------------------------------------- 37 | 38 | # If your documentation needs a minimal Sphinx version, state it here. 39 | #needs_sphinx = '1.0' 40 | 41 | # Add any Sphinx extension module names here, as strings. They can be 42 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. 43 | extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode'] 44 | 45 | # Add any paths that contain templates here, relative to this directory. 46 | templates_path = ['_templates'] 47 | 48 | # The suffix of source filenames. 49 | source_suffix = '.rst' 50 | 51 | # The encoding of source files. 52 | #source_encoding = 'utf-8-sig' 53 | 54 | # The master toctree document. 55 | master_doc = 'index' 56 | 57 | # General information about the project. 58 | project = u'datakit-github' 59 | copyright = u"2019, Serdar Tumgoren" 60 | 61 | # The version info for the project you're documenting, acts as replacement 62 | # for |version| and |release|, also used in various other places throughout 63 | # the built documents. 64 | # 65 | # The short X.Y version. 66 | version = datakit_github.__version__ 67 | # The full version, including alpha/beta/rc tags. 68 | release = datakit_github.__version__ 69 | 70 | # The language for content autogenerated by Sphinx. Refer to documentation 71 | # for a list of supported languages. 72 | #language = None 73 | 74 | # There are two options for replacing |today|: either, you set today to 75 | # some non-false value, then it is used: 76 | #today = '' 77 | # Else, today_fmt is used as the format for a strftime call. 78 | #today_fmt = '%B %d, %Y' 79 | 80 | # List of patterns, relative to source directory, that match files and 81 | # directories to ignore when looking for source files. 82 | exclude_patterns = ['_build'] 83 | 84 | # The reST default role (used for this markup: `text`) to use for all 85 | # documents. 86 | #default_role = None 87 | 88 | # If true, '()' will be appended to :func: etc. cross-reference text. 89 | #add_function_parentheses = True 90 | 91 | # If true, the current module name will be prepended to all description 92 | # unit titles (such as .. function::). 93 | #add_module_names = True 94 | 95 | # If true, sectionauthor and moduleauthor directives will be shown in the 96 | # output. They are ignored by default. 97 | #show_authors = False 98 | 99 | # The name of the Pygments (syntax highlighting) style to use. 100 | pygments_style = 'sphinx' 101 | 102 | # A list of ignored prefixes for module index sorting. 103 | #modindex_common_prefix = [] 104 | 105 | # If true, keep warnings as "system message" paragraphs in the built 106 | # documents. 107 | #keep_warnings = False 108 | 109 | 110 | # -- Options for HTML output ------------------------------------------- 111 | 112 | # The theme to use for HTML and HTML Help pages. See the documentation for 113 | # a list of builtin themes. 114 | html_theme = 'alabaster' 115 | 116 | # Theme options are theme-specific and customize the look and feel of a 117 | # theme further. For a list of options available for each theme, see the 118 | # documentation. 119 | html_theme_options = { 120 | 'github_user': 'associatedpress', 121 | 'github_repo': 'datakit-github', 122 | 'github_button': True, 123 | 'fixed_sidebar': True, 124 | 'description': 'Light-weight GitHub integration for datakit workflows.' 125 | } 126 | 127 | # Add any paths that contain custom themes here, relative to this directory. 128 | #html_theme_path = [] 129 | 130 | # The name for this set of Sphinx documents. If None, it defaults to 131 | # " v documentation". 132 | #html_title = None 133 | 134 | # A shorter title for the navigation bar. Default is the same as 135 | # html_title. 136 | #html_short_title = None 137 | 138 | # The name of an image file (relative to this directory) to place at the 139 | # top of the sidebar. 140 | #html_logo = None 141 | 142 | # The name of an image file (within the static path) to use as favicon 143 | # of the docs. This file should be a Windows icon file (.ico) being 144 | # 16x16 or 32x32 pixels large. 145 | #html_favicon = None 146 | 147 | # Add any paths that contain custom static files (such as style sheets) 148 | # here, relative to this directory. They are copied after the builtin 149 | # static files, so a file named "default.css" will overwrite the builtin 150 | # "default.css". 151 | html_static_path = ['_static'] 152 | 153 | # If not '', a 'Last updated on:' timestamp is inserted at every page 154 | # bottom, using the given strftime format. 155 | #html_last_updated_fmt = '%b %d, %Y' 156 | 157 | # If true, SmartyPants will be used to convert quotes and dashes to 158 | # typographically correct entities. 159 | #html_use_smartypants = True 160 | 161 | # Custom sidebar templates, maps document names to template names. 162 | html_sidebars = { 163 | '**': [ 164 | 'about.html', 165 | 'navigation.html', 166 | 'relations.html', 167 | 'searchbox.html', 168 | ] 169 | } 170 | 171 | # Additional templates that should be rendered to pages, maps page names 172 | # to template names. 173 | #html_additional_pages = {} 174 | 175 | # If false, no module index is generated. 176 | #html_domain_indices = True 177 | 178 | # If false, no index is generated. 179 | #html_use_index = True 180 | 181 | # If true, the index is split into individual pages for each letter. 182 | #html_split_index = False 183 | 184 | # If true, links to the reST sources are added to the pages. 185 | #html_show_sourcelink = True 186 | 187 | # If true, "Created using Sphinx" is shown in the HTML footer. 188 | # Default is True. 189 | #html_show_sphinx = True 190 | 191 | # If true, "(C) Copyright ..." is shown in the HTML footer. 192 | # Default is True. 193 | #html_show_copyright = True 194 | 195 | # If true, an OpenSearch description file will be output, and all pages 196 | # will contain a tag referring to it. The value of this option 197 | # must be the base URL from which the finished HTML is served. 198 | #html_use_opensearch = '' 199 | 200 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 201 | #html_file_suffix = None 202 | 203 | # Output file base name for HTML help builder. 204 | htmlhelp_basename = 'datakit-githubdoc' 205 | 206 | 207 | # -- Options for LaTeX output ------------------------------------------ 208 | 209 | latex_elements = { 210 | # The paper size ('letterpaper' or 'a4paper'). 211 | #'papersize': 'letterpaper', 212 | 213 | # The font size ('10pt', '11pt' or '12pt'). 214 | #'pointsize': '10pt', 215 | 216 | # Additional stuff for the LaTeX preamble. 217 | #'preamble': '', 218 | } 219 | 220 | # Grouping the document tree into LaTeX files. List of tuples 221 | # (source start file, target name, title, author, documentclass 222 | # [howto/manual]). 223 | latex_documents = [ 224 | ('index', 'datakit-github.tex', 225 | u'datakit-github Documentation', 226 | u'Serdar Tumgoren', 'manual'), 227 | ] 228 | 229 | # The name of an image file (relative to this directory) to place at 230 | # the top of the title page. 231 | #latex_logo = None 232 | 233 | # For "manual" documents, if this is true, then toplevel headings 234 | # are parts, not chapters. 235 | #latex_use_parts = False 236 | 237 | # If true, show page references after internal links. 238 | #latex_show_pagerefs = False 239 | 240 | # If true, show URL addresses after external links. 241 | #latex_show_urls = False 242 | 243 | # Documents to append as an appendix to all manuals. 244 | #latex_appendices = [] 245 | 246 | # If false, no module index is generated. 247 | #latex_domain_indices = True 248 | 249 | 250 | # -- Options for manual page output ------------------------------------ 251 | 252 | # One entry per manual page. List of tuples 253 | # (source start file, name, description, authors, manual section). 254 | man_pages = [ 255 | ('index', 'datakit-github', 256 | u'datakit-github Documentation', 257 | [u'Serdar Tumgoren'], 1) 258 | ] 259 | 260 | # If true, show URL addresses after external links. 261 | #man_show_urls = False 262 | 263 | 264 | # -- Options for Texinfo output ---------------------------------------- 265 | 266 | # Grouping the document tree into Texinfo files. List of tuples 267 | # (source start file, target name, title, author, 268 | # dir menu entry, description, category) 269 | texinfo_documents = [ 270 | ('index', 'datakit-github', 271 | u'datakit-github Documentation', 272 | u'Serdar Tumgoren', 273 | 'datakit-github', 274 | 'One line description of project.', 275 | 'Miscellaneous'), 276 | ] 277 | 278 | # Documents to append as an appendix to all manuals. 279 | #texinfo_appendices = [] 280 | 281 | # If false, no module index is generated. 282 | #texinfo_domain_indices = True 283 | 284 | # How to display URL addresses: 'footnote', 'no', or 'inline'. 285 | #texinfo_show_urls = 'footnote' 286 | 287 | # If true, do not generate a @detailmenu in the "Top" node's menu. 288 | #texinfo_no_detailmenu = False 289 | -------------------------------------------------------------------------------- /docs/contributing.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../CONTRIBUTING.rst 2 | -------------------------------------------------------------------------------- /docs/datakit_github.commands.rst: -------------------------------------------------------------------------------- 1 | datakit_github.commands package 2 | =============================== 3 | 4 | Submodules 5 | ---------- 6 | 7 | datakit_github.commands.integrate module 8 | ---------------------------------------- 9 | 10 | .. automodule:: datakit_github.commands.integrate 11 | :members: 12 | :undoc-members: 13 | :show-inheritance: 14 | 15 | 16 | Module contents 17 | --------------- 18 | 19 | .. automodule:: datakit_github.commands 20 | :members: 21 | :undoc-members: 22 | :show-inheritance: 23 | -------------------------------------------------------------------------------- /docs/datakit_github.rst: -------------------------------------------------------------------------------- 1 | datakit\_github package 2 | ======================= 3 | 4 | Subpackages 5 | ----------- 6 | 7 | .. toctree:: 8 | :maxdepth: 4 9 | 10 | datakit_github.commands 11 | 12 | Submodules 13 | ---------- 14 | 15 | datakit\_github.github\_api module 16 | ---------------------------------- 17 | 18 | .. automodule:: datakit_github.github_api 19 | :members: 20 | :undoc-members: 21 | :show-inheritance: 22 | 23 | datakit\_github.project\_mixin module 24 | ------------------------------------- 25 | 26 | .. automodule:: datakit_github.project_mixin 27 | :members: 28 | :undoc-members: 29 | :show-inheritance: 30 | 31 | datakit\_github.repository module 32 | --------------------------------- 33 | 34 | .. automodule:: datakit_github.repository 35 | :members: 36 | :undoc-members: 37 | :show-inheritance: 38 | 39 | Module contents 40 | --------------- 41 | 42 | .. automodule:: datakit_github 43 | :members: 44 | :undoc-members: 45 | :show-inheritance: 46 | -------------------------------------------------------------------------------- /docs/history.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../HISTORY.rst 2 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. datakit-github documentation master file 2 | 3 | .. include:: ../README.rst 4 | 5 | Documentation 6 | ============= 7 | 8 | .. toctree:: 9 | install 10 | usage 11 | contributing 12 | authors 13 | history 14 | 15 | Indices and tables 16 | ================== 17 | 18 | * :ref:`genindex` 19 | * :ref:`modindex` 20 | * :ref:`search` 21 | 22 | Credits 23 | ======== 24 | 25 | This plugin was created with Cookiecutter_ and the `associatedpress/cookiecutter-datakit-plugin`_ 26 | project template (a modified version of the most excellent `audreyr/cookiecutter-pypackage`_). 27 | 28 | 29 | .. _Cookiecutter: https://github.com/audreyr/cookiecutter 30 | .. _`associatedpress/cookiecutter-datakit-plugin`: https://github.com/associatedpress/cookiecutter-datakit-plugin 31 | .. _`audreyr/cookiecutter-pypackage`: https://github.com/audreyr/cookiecutter-pypackage 32 | -------------------------------------------------------------------------------- /docs/install.rst: -------------------------------------------------------------------------------- 1 | .. _install: 2 | 3 | Installation 4 | ============ 5 | 6 | Preliminary Git and GitHub setup 7 | -------------------------------- 8 | 9 | .. note:: 10 | 11 | Existing users of git/GitHub should be able to skip a number of steps 12 | in this preliminary setup section. 13 | 14 | First, some preliminary git/GitHub setup that will allow you to push and pull code securely: 15 | 16 | * `Install git`_ 17 | * Configure git user and email 18 | 19 | .. code:: 20 | 21 | # NOTE: Substitute your own name and email below!! 22 | git config --global user.name "John Doe" 23 | git config --global user.email johndoe@example.com 24 | 25 | 26 | * Create a `GitHub`_ account. 27 | * `Generate an ssh keypair`_ (if you haven't already) 28 | * `Add your ssh public key to GitHub`_ 29 | 30 | 31 | Install DataKit libraries 32 | -------------------------- 33 | 34 | Next, install the core DataKit_ library and the datakit-project_ and datakit-github_ plugins: 35 | 36 | .. code:: 37 | 38 | pip install --user datakit-core datakit-project datakit-github 39 | 40 | 41 | Generate GitHub API token 42 | -------------------------- 43 | 44 | Next, you must generate a `personal GitHub API token`_ with all permissions for the **repo** scope. 45 | This will enable datakit to automate interactions with the GitHub API (e.g. to auto-generate a project on GitHub). 46 | 47 | Add API token to config 48 | ----------------------- 49 | 50 | With the API token in hand, store it in the configuration file for the *datakit-github* plugin. 51 | This file must be located inside the home directory for datakit configurations. 52 | 53 | On Mac/Linux systems, you should create `~/.datakit/plugins/datakit-github/config.json` file with 54 | the below commands:: 55 | 56 | # First ensure the plugin directory exists 57 | mkdir -p ~/.datakit/plugins/datakit-github/ 58 | # Create a blank configuration file 59 | touch ~/.datakit/plugins/datakit-github/config.json 60 | 61 | Lastly, edit the newly created file so that it contains the below, replacing 62 | `GITHUB_API_TOKEN` with your actual key:: 63 | 64 | {"github_api_key": "GITHUB_API_TOKEN"} 65 | 66 | .. note:: 67 | 68 | Please be sure to avoid extraneous white space and preserve the double quotes. This must be valid JSON!! 69 | 70 | 71 | .. _GitHub: https://github.com 72 | .. _`Generate an ssh keypair`: https://help.github.com/en/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent 73 | .. _`Add your ssh public key to GitHub`: https://help.github.com/en/articles/adding-a-new-ssh-key-to-your-github-account 74 | .. _`personal GitHub API token`: https://github.com/settings/tokens 75 | .. _datakit-github: https://github.com/associatedpress/datakit-github 76 | .. _`Install git`: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git 77 | .. _DataKit: https://github.com/associatedpress/datakit-core 78 | .. _datakit-github docs: https://datakit-github.readthedocs.io/en/latest/ 79 | .. _datakit-project: https://datakit-project.readthedocs.io/en/latest/ 80 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | REM Command file for Sphinx documentation 4 | 5 | if "%SPHINXBUILD%" == "" ( 6 | set SPHINXBUILD=sphinx-build 7 | ) 8 | set BUILDDIR=_build 9 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . 10 | set I18NSPHINXOPTS=%SPHINXOPTS% . 11 | if NOT "%PAPER%" == "" ( 12 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% 13 | set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% 14 | ) 15 | 16 | if "%1" == "" goto help 17 | 18 | if "%1" == "help" ( 19 | :help 20 | echo.Please use `make ^` where ^ is one of 21 | echo. html to make standalone HTML files 22 | echo. dirhtml to make HTML files named index.html in directories 23 | echo. singlehtml to make a single large HTML file 24 | echo. pickle to make pickle files 25 | echo. json to make JSON files 26 | echo. htmlhelp to make HTML files and a HTML help project 27 | echo. qthelp to make HTML files and a qthelp project 28 | echo. devhelp to make HTML files and a Devhelp project 29 | echo. epub to make an epub 30 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter 31 | echo. text to make text files 32 | echo. man to make manual pages 33 | echo. texinfo to make Texinfo files 34 | echo. gettext to make PO message catalogs 35 | echo. changes to make an overview over all changed/added/deprecated items 36 | echo. xml to make Docutils-native XML files 37 | echo. pseudoxml to make pseudoxml-XML files for display purposes 38 | echo. linkcheck to check all external links for integrity 39 | echo. doctest to run all doctests embedded in the documentation if enabled 40 | goto end 41 | ) 42 | 43 | if "%1" == "clean" ( 44 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i 45 | del /q /s %BUILDDIR%\* 46 | goto end 47 | ) 48 | 49 | 50 | %SPHINXBUILD% 2> nul 51 | if errorlevel 9009 ( 52 | echo. 53 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 54 | echo.installed, then set the SPHINXBUILD environment variable to point 55 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 56 | echo.may add the Sphinx directory to PATH. 57 | echo. 58 | echo.If you don't have Sphinx installed, grab it from 59 | echo.http://sphinx-doc.org/ 60 | exit /b 1 61 | ) 62 | 63 | if "%1" == "html" ( 64 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html 65 | if errorlevel 1 exit /b 1 66 | echo. 67 | echo.Build finished. The HTML pages are in %BUILDDIR%/html. 68 | goto end 69 | ) 70 | 71 | if "%1" == "dirhtml" ( 72 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml 73 | if errorlevel 1 exit /b 1 74 | echo. 75 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. 76 | goto end 77 | ) 78 | 79 | if "%1" == "singlehtml" ( 80 | %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml 81 | if errorlevel 1 exit /b 1 82 | echo. 83 | echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. 84 | goto end 85 | ) 86 | 87 | if "%1" == "pickle" ( 88 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle 89 | if errorlevel 1 exit /b 1 90 | echo. 91 | echo.Build finished; now you can process the pickle files. 92 | goto end 93 | ) 94 | 95 | if "%1" == "json" ( 96 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json 97 | if errorlevel 1 exit /b 1 98 | echo. 99 | echo.Build finished; now you can process the JSON files. 100 | goto end 101 | ) 102 | 103 | if "%1" == "htmlhelp" ( 104 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp 105 | if errorlevel 1 exit /b 1 106 | echo. 107 | echo.Build finished; now you can run HTML Help Workshop with the ^ 108 | .hhp project file in %BUILDDIR%/htmlhelp. 109 | goto end 110 | ) 111 | 112 | if "%1" == "qthelp" ( 113 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp 114 | if errorlevel 1 exit /b 1 115 | echo. 116 | echo.Build finished; now you can run "qcollectiongenerator" with the ^ 117 | .qhcp project file in %BUILDDIR%/qthelp, like this: 118 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\datakit_github.qhcp 119 | echo.To view the help file: 120 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\datakit_github.ghc 121 | goto end 122 | ) 123 | 124 | if "%1" == "devhelp" ( 125 | %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp 126 | if errorlevel 1 exit /b 1 127 | echo. 128 | echo.Build finished. 129 | goto end 130 | ) 131 | 132 | if "%1" == "epub" ( 133 | %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub 134 | if errorlevel 1 exit /b 1 135 | echo. 136 | echo.Build finished. The epub file is in %BUILDDIR%/epub. 137 | goto end 138 | ) 139 | 140 | if "%1" == "latex" ( 141 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 142 | if errorlevel 1 exit /b 1 143 | echo. 144 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. 145 | goto end 146 | ) 147 | 148 | if "%1" == "latexpdf" ( 149 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 150 | cd %BUILDDIR%/latex 151 | make all-pdf 152 | cd %BUILDDIR%/.. 153 | echo. 154 | echo.Build finished; the PDF files are in %BUILDDIR%/latex. 155 | goto end 156 | ) 157 | 158 | if "%1" == "latexpdfja" ( 159 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 160 | cd %BUILDDIR%/latex 161 | make all-pdf-ja 162 | cd %BUILDDIR%/.. 163 | echo. 164 | echo.Build finished; the PDF files are in %BUILDDIR%/latex. 165 | goto end 166 | ) 167 | 168 | if "%1" == "text" ( 169 | %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text 170 | if errorlevel 1 exit /b 1 171 | echo. 172 | echo.Build finished. The text files are in %BUILDDIR%/text. 173 | goto end 174 | ) 175 | 176 | if "%1" == "man" ( 177 | %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man 178 | if errorlevel 1 exit /b 1 179 | echo. 180 | echo.Build finished. The manual pages are in %BUILDDIR%/man. 181 | goto end 182 | ) 183 | 184 | if "%1" == "texinfo" ( 185 | %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo 186 | if errorlevel 1 exit /b 1 187 | echo. 188 | echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. 189 | goto end 190 | ) 191 | 192 | if "%1" == "gettext" ( 193 | %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale 194 | if errorlevel 1 exit /b 1 195 | echo. 196 | echo.Build finished. The message catalogs are in %BUILDDIR%/locale. 197 | goto end 198 | ) 199 | 200 | if "%1" == "changes" ( 201 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes 202 | if errorlevel 1 exit /b 1 203 | echo. 204 | echo.The overview file is in %BUILDDIR%/changes. 205 | goto end 206 | ) 207 | 208 | if "%1" == "linkcheck" ( 209 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck 210 | if errorlevel 1 exit /b 1 211 | echo. 212 | echo.Link check complete; look for any errors in the above output ^ 213 | or in %BUILDDIR%/linkcheck/output.txt. 214 | goto end 215 | ) 216 | 217 | if "%1" == "doctest" ( 218 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest 219 | if errorlevel 1 exit /b 1 220 | echo. 221 | echo.Testing of doctests in the sources finished, look at the ^ 222 | results in %BUILDDIR%/doctest/output.txt. 223 | goto end 224 | ) 225 | 226 | if "%1" == "xml" ( 227 | %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml 228 | if errorlevel 1 exit /b 1 229 | echo. 230 | echo.Build finished. The XML files are in %BUILDDIR%/xml. 231 | goto end 232 | ) 233 | 234 | if "%1" == "pseudoxml" ( 235 | %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml 236 | if errorlevel 1 exit /b 1 237 | echo. 238 | echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. 239 | goto end 240 | ) 241 | 242 | :end 243 | -------------------------------------------------------------------------------- /docs/modules.rst: -------------------------------------------------------------------------------- 1 | datakit_github 2 | ============== 3 | 4 | .. toctree:: 5 | :maxdepth: 4 6 | 7 | datakit_github 8 | -------------------------------------------------------------------------------- /docs/readme.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../README.rst 2 | -------------------------------------------------------------------------------- /docs/usage.rst: -------------------------------------------------------------------------------- 1 | .. _usage: 2 | 3 | Usage 4 | ===== 5 | 6 | Create a new project using the datakit-project_ plugin. For example, 7 | you could try AP's template for R-based projects:: 8 | 9 | datakit project create -t https://github.com/associatedpress/cookiecutter-r-project.git 10 | 11 | The above command will prompt you for various bits of information, including a project name. 12 | Let's assume we chose `awesome-proj` as the name. 13 | 14 | To integrate the project with GitHub, navigate into the newly created 15 | project directory and execute the following command:: 16 | 17 | cd awesome-proj 18 | datakit github integrate 19 | 20 | The above should trigger a series of prompts that allow you to select the GitHub account where the 21 | new repo should be created, and whether to make the repo private or public. 22 | 23 | The command will auto-generate the GitHub project, link your local code to the new project, and 24 | push the newly generated project skeleton to GitHub as your first commit. 25 | 26 | .. note:: The command will warn you if a project name already exists on the GitHub account. 27 | In such a case, you must either choose a different account (e.g. if 28 | you're a member of another GitHub organization), rename the project, or remove the previously 29 | existing project from GitHub. 30 | 31 | 32 | .. _datakit-github docs: https://datakit-github.readthedocs.io/en/latest/ 33 | .. _datakit-project: https://datakit-project.readthedocs.io/en/latest/ 34 | -------------------------------------------------------------------------------- /requirements-dev.txt: -------------------------------------------------------------------------------- 1 | pip 2 | wheel 3 | bumpversion==0.6.0 4 | watchdog==2.1.9 5 | flake8==4.0.1 6 | tox==3.25.1 7 | coverage==6.4.2 8 | # Peg docutils until below bug is resolved 9 | # https://github.com/sphinx-doc/sphinx/issues/3212 10 | docutils==0.12 11 | Sphinx==1.4.8 12 | pytest==7.1.2 13 | pytest-vcr==1.0.2 14 | twine==4.0.1 15 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | cliff==3.10.1 2 | datakit-core>=0.3.0 3 | PyGithub==1.55 4 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [bumpversion] 2 | current_version = 0.2.1 3 | commit = True 4 | tag = True 5 | 6 | [bumpversion:file:setup.py] 7 | 8 | [bumpversion:file:datakit_github/__init__.py] 9 | 10 | [flake8] 11 | max-line-length = 130 12 | per-file-ignores = 13 | datakit_github/commands/__init__.py:F401 14 | exclude = docs, 15 | __pycache__, 16 | .git 17 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | datakit-github 6 | --------------- 7 | 8 | This plugin provides light-weight GitHub integration for the `DataKit command-line tool `_. 9 | 10 | It's intended to streamline the process of generating a GitHub project and linking it to a local 11 | directory containing a newly created project skeleton. 12 | 13 | DataKit is a project by The Associated Press designed to streamline data analysis workflows. 14 | To learn more about the wider DataKit ecosystem and how AP uses it, check out the 15 | `official documentation for DataKit `_. 16 | 17 | More information on the datakit-github plugin can be found below: 18 | 19 | * Documentation: http://datakit-github.readthedocs.io/en/latest/ 20 | * GitHub: https://github.com/associatedpress/datakit-github 21 | * PyPI: https://pypi.python.org/pypi/datakit-github 22 | * Free and open source software: `ISC license `_ 23 | 24 | """ 25 | 26 | from setuptools import setup, find_packages 27 | 28 | requirements = [ 29 | 'cliff', 30 | 'datakit-core', 31 | 'PyGithub', 32 | ] 33 | 34 | test_requirements = [ 35 | 'flake8==4.0.1', 36 | 'pytest==7.1.2', 37 | 'pytest-vcr==1.0.2' 38 | ] 39 | 40 | setup( 41 | name='datakit-github', 42 | version='0.2.1', 43 | description="Light-weight GitHub integration for datakit workflows.", 44 | long_description=__doc__, 45 | long_description_content_type='text/x-rst', 46 | author="Serdar Tumgoren", 47 | author_email='zstumgoren@gmail.com', 48 | url='https://github.com/associatedpress/datakit-github', 49 | packages=find_packages(), 50 | include_package_data=True, 51 | entry_points={ 52 | 'datakit.plugins': [ 53 | 'github integrate=datakit_github.commands:Integrate', 54 | ] 55 | }, 56 | install_requires=requirements, 57 | license="ISC license", 58 | zip_safe=False, 59 | keywords='datakit', 60 | classifiers=[ 61 | 'Development Status :: 5 - Production/Stable', 62 | 'Environment :: Console', 63 | 'Intended Audience :: Developers', 64 | 'License :: OSI Approved :: ISC License (ISCL)', 65 | 'Natural Language :: English', 66 | 'Programming Language :: Python :: 3', 67 | 'Programming Language :: Python :: 3.5', 68 | 'Programming Language :: Python :: 3.6', 69 | 'Programming Language :: Python :: 3.7', 70 | 'Programming Language :: Python :: 3.8', 71 | 'Programming Language :: Python :: 3.9', 72 | ], 73 | test_suite='tests', 74 | tests_require=test_requirements, 75 | project_urls={ 76 | "Documentation": "http://datakit-github.readthedocs.io/en/latest/", 77 | "Maintainer": "https://github.com/associatedpress", 78 | "Source": "https://github.com/associatedpress/datakit-github", 79 | "Tracker": "https://github.com/associatedpress/datakit-github/issues" 80 | }, 81 | ) 82 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/associatedpress/datakit-github/bb17df41c1298e3411d1403b14402da842a43486/tests/__init__.py -------------------------------------------------------------------------------- /tests/cassettes/test_accounts.yaml: -------------------------------------------------------------------------------- 1 | interactions: 2 | - request: 3 | body: null 4 | headers: 5 | Accept: 6 | - '*/*' 7 | Accept-Encoding: 8 | - gzip, deflate 9 | Connection: 10 | - keep-alive 11 | User-Agent: 12 | - PyGithub/Python 13 | authorization: 14 | - DUMMY 15 | method: GET 16 | uri: https://api.github.com/user/orgs 17 | response: 18 | body: 19 | string: !!binary | 20 | H4sIAAAAAAAAA62X7WrbMBSGb0X479Imjuu1KZQxSDc6cLuyho2NURRbcZQolpHkdEkp7DZ2e7uS 21 | HTkfs1yHWMb/GuPnVaif8/rkx7PDeEwT59KJeJgtSKJCxrPI6Tg0ci4HnnfhdZyER+RRf3aC4fXq 22 | bj5Yfe9/yPC3dBp9ZMvxbL4O1vEamEwwuGmqVCovu12c0tOYqmk2Pg35ostFLLvlUwRJuXy05Lo5 23 | BeeRJXxhe3yDAT/lfG6P55T+D0mZEXt8gwG/IIsxEfYBW+65u/njBaLSbMxo+Ng00cSLwXiJFRbl 24 | B5RflP3t080kESFPFDyL/EFn3dybd8urM/hqEZGhoKmiXFvmvHT+K/d5paY8+cQzkeSPUyvme97Z 25 | ef+4cyNw7t4L4qsrAI/7Uz6qrncGZ++diVt7Z+LW3pl4A+/MgDa8MxPb9m4jT5V4ScZYUT2+JGJJ 26 | ydPWugv/zPPd49bF7u0wcIP7mtYVTqkr3A6xd21PWmu2J60N25MN5NqzbXi1D2umVO9glW3MqFLK 27 | eZgSxFOSIAkNFhK0e7ehBU1oEqOUYTXhYmF0HpaShxQrEqWCyF3rue5bf+D2jgt4/et2NvKDh/f1 28 | au/1aXU9LJH2OpYDrK0sB1jLWQ5o4Gg5og1Vy5nNjHUPGrt1qVJZQ0XtLmEk1K/mvYiDnj8Y1BHR 29 | D4Yj/66uiOWz6mpocPYSmri1giZuLaCJN9DPDGhDPjOxmXqH9z53Y0+lerotY44Z4hN0B+Zd78xD 30 | VCLFUSgItCJScNuECqnQRBDSQbBQQlFOSSLpEj5KhZMIi4iuSdRBjCZzEiFJlE7duYygWDOmJIpg 31 | TUXQwHnoKKFQuuiLglPkqTEIOhRui2Z6E8WMysV2Lej3ev3euXd+vJdvnoLhzdPtOvBqraOVJ9ad 32 | idew/WBUZFhPR0WG9YhUZDSYk4qUNoalIrbZxBwu651hlSPzlfz9/UcQlMIrAzpajwce80zBFHCx 33 | UoSB/zF6k3tuCK0vzKk6CRndmex7A/+tV6PYb9xgPXdvZ4HejY//sDKPqqtwgbJ3twhbS1uErW0t 34 | wg00LeJt+FnMa13MrTCVYg43fqEThGHLzeIYjxnRVb2Adj4BK6HHOWe61uEKjmE31lWcCj6DdUO3 35 | 789/tzazUXoSAAA= 36 | headers: 37 | Access-Control-Allow-Origin: 38 | - '*' 39 | Access-Control-Expose-Headers: 40 | - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, 41 | X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, 42 | X-GitHub-Media-Type 43 | Cache-Control: 44 | - private, max-age=60, s-maxage=60 45 | Content-Encoding: 46 | - gzip 47 | Content-Security-Policy: 48 | - default-src 'none' 49 | Content-Type: 50 | - application/json; charset=utf-8 51 | Date: 52 | - Fri, 06 Sep 2019 17:28:03 GMT 53 | ETag: 54 | - W/"f6153453e8455ef3f55031d134f82d15" 55 | Referrer-Policy: 56 | - origin-when-cross-origin, strict-origin-when-cross-origin 57 | Server: 58 | - GitHub.com 59 | Status: 60 | - 200 OK 61 | Strict-Transport-Security: 62 | - max-age=31536000; includeSubdomains; preload 63 | Transfer-Encoding: 64 | - chunked 65 | Vary: 66 | - Accept, Authorization, Cookie, X-GitHub-OTP 67 | - Accept-Encoding 68 | X-Accepted-OAuth-Scopes: 69 | - admin:org, read:org, repo, user, write:org 70 | X-Content-Type-Options: 71 | - nosniff 72 | X-Frame-Options: 73 | - deny 74 | X-GitHub-Media-Type: 75 | - github.v3; format=json 76 | X-GitHub-Request-Id: 77 | - EF3D:15CE:F3CCB:11E0BD:5D729722 78 | X-OAuth-Scopes: 79 | - admin:org, admin:repo_hook, delete_repo, notifications, read:packages, repo, 80 | write:discussion, write:packages 81 | X-RateLimit-Limit: 82 | - '5000' 83 | X-RateLimit-Remaining: 84 | - '4999' 85 | X-RateLimit-Reset: 86 | - '1567794483' 87 | X-XSS-Protection: 88 | - 1; mode=block 89 | status: 90 | code: 200 91 | message: OK 92 | - request: 93 | body: null 94 | headers: 95 | Accept: 96 | - '*/*' 97 | Accept-Encoding: 98 | - gzip, deflate 99 | Connection: 100 | - keep-alive 101 | User-Agent: 102 | - PyGithub/Python 103 | authorization: 104 | - DUMMY 105 | method: GET 106 | uri: https://api.github.com/user 107 | response: 108 | body: 109 | string: !!binary | 110 | H4sIAAAAAAAAA52UXW/aMBiF/0rkayAfa9kSqWqrVbuYxLSpdJp6g4xjEiPHjvwBoqj/fccJg8LF 111 | pHCVxH7P48Pr97AnUldCkYK8WeebShuuyIiIkhSf8ixJRkTpki/CN5k9/Zr+/vNDsvXsdrZ+3KKO 112 | bqijZuGNxH7tXGuLOO4XbTqphKv90ltumFaOKzdhuol93JHvN3c3IFTmwOiOwMIFqxUHTK8Fy8Zn 113 | VmvXyAsD/bmd4Kx0paXUWxAuDf//kPiog73+XajqKgZ0+1i7mqNn+CnvoQHCuqGGOs0+Dg9cTaBY 114 | XIPh5UBTBxUsbRXc7GPDW93h/NIyI1ontBpq7kwLljYVVeKNXsOC1gIRbA210Wmg5RsM3lBxL9rH 115 | rREbynahJYYzLjZo8VXACzV4btdyTPwLxiA0XDi+oGUTorii0nIEjzah4Jmbkppofgon5rqlaoe9 116 | B1ygWmlTrrU3ikphG7CWiHSfJalZ1/aAoSr6ZqhiwjI9ir4+htY0VITgnkLyUIWlkBxs18JwupQw 117 | obyU4AqN4ickPjqdF0nOnDfcRPARYbKj54On6PvRVPTTaAS9mYDa+qUUbNFfT3Hz+bjSDTUpsvxf 118 | yBBUUuTTD5nDJ3YZbDlcBHWwg3+SL+M0Gyf5PEmLbFokyStO8W35sSbNxyjL0nmWFOltkaav5P0v 119 | yD0ixvsEAAA= 120 | headers: 121 | Access-Control-Allow-Origin: 122 | - '*' 123 | Access-Control-Expose-Headers: 124 | - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, 125 | X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, 126 | X-GitHub-Media-Type 127 | Cache-Control: 128 | - private, max-age=60, s-maxage=60 129 | Content-Encoding: 130 | - gzip 131 | Content-Security-Policy: 132 | - default-src 'none' 133 | Content-Type: 134 | - application/json; charset=utf-8 135 | Date: 136 | - Fri, 06 Sep 2019 17:28:03 GMT 137 | ETag: 138 | - W/"566ed2d612496c35fdf0e7114d906425" 139 | Last-Modified: 140 | - Wed, 21 Aug 2019 20:15:11 GMT 141 | Referrer-Policy: 142 | - origin-when-cross-origin, strict-origin-when-cross-origin 143 | Server: 144 | - GitHub.com 145 | Status: 146 | - 200 OK 147 | Strict-Transport-Security: 148 | - max-age=31536000; includeSubdomains; preload 149 | Transfer-Encoding: 150 | - chunked 151 | Vary: 152 | - Accept, Authorization, Cookie, X-GitHub-OTP 153 | - Accept-Encoding 154 | X-Accepted-OAuth-Scopes: 155 | - '' 156 | X-Content-Type-Options: 157 | - nosniff 158 | X-Frame-Options: 159 | - deny 160 | X-GitHub-Media-Type: 161 | - github.v3; format=json 162 | X-GitHub-Request-Id: 163 | - EF3D:15CE:F3D07:11E0E6:5D729723 164 | X-OAuth-Scopes: 165 | - admin:org, admin:repo_hook, delete_repo, notifications, read:packages, repo, 166 | write:discussion, write:packages 167 | X-RateLimit-Limit: 168 | - '5000' 169 | X-RateLimit-Remaining: 170 | - '4998' 171 | X-RateLimit-Reset: 172 | - '1567794483' 173 | X-XSS-Protection: 174 | - 1; mode=block 175 | status: 176 | code: 200 177 | message: OK 178 | version: 1 179 | -------------------------------------------------------------------------------- /tests/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/associatedpress/datakit-github/bb17df41c1298e3411d1403b14402da842a43486/tests/commands/__init__.py -------------------------------------------------------------------------------- /tests/commands/cassettes/test_choose_default_account.yaml: -------------------------------------------------------------------------------- 1 | interactions: 2 | - request: 3 | body: null 4 | headers: 5 | Accept: 6 | - '*/*' 7 | Accept-Encoding: 8 | - gzip, deflate 9 | Connection: 10 | - keep-alive 11 | User-Agent: 12 | - PyGithub/Python 13 | authorization: 14 | - DUMMY 15 | method: GET 16 | uri: https://api.github.com/user/orgs 17 | response: 18 | body: 19 | string: !!binary | 20 | H4sIAAAAAAAAA62X7WrbMBSGb0X479Imjuu1KZQxSDc6cLuyho2NURRbcZQolpHkdEkp7DZ2e7uS 21 | HTkfs1yHWMb/GuPnVaif8/rkx7PDeEwT59KJeJgtSKJCxrPI6Tg0ci4HnnfhdZyER+RRf3aC4fXq 22 | bj5Yfe9/yPC3dBp9ZMvxbL4O1vEamEwwuGmqVCovu12c0tOYqmk2Pg35ostFLLvlUwRJuXy05Lo5 23 | BeeRJXxhe3yDAT/lfG6P55T+D0mZEXt8gwG/IIsxEfYBW+65u/njBaLSbMxo+Ng00cSLwXiJFRbl 24 | B5RflP3t080kESFPFDyL/EFn3dybd8urM/hqEZGhoKmiXFvmvHT+K/d5paY8+cQzkeSPUyvme97Z 25 | ef+4cyNw7t4L4qsrAI/7Uz6qrncGZ++diVt7Z+LW3pl4A+/MgDa8MxPb9m4jT5V4ScZYUT2+JGJJ 26 | ydPWugv/zPPd49bF7u0wcIP7mtYVTqkr3A6xd21PWmu2J60N25MN5NqzbXi1D2umVO9glW3MqFLK 27 | eZgSxFOSIAkNFhK0e7ehBU1oEqOUYTXhYmF0HpaShxQrEqWCyF3rue5bf+D2jgt4/et2NvKDh/f1 28 | au/1aXU9LJH2OpYDrK0sB1jLWQ5o4Gg5og1Vy5nNjHUPGrt1qVJZQ0XtLmEk1K/mvYiDnj8Y1BHR 29 | D4Yj/66uiOWz6mpocPYSmri1giZuLaCJN9DPDGhDPjOxmXqH9z53Y0+lerotY44Z4hN0B+Zd78xD 30 | VCLFUSgItCJScNuECqnQRBDSQbBQQlFOSSLpEj5KhZMIi4iuSdRBjCZzEiFJlE7duYygWDOmJIpg 31 | TUXQwHnoKKFQuuiLglPkqTEIOhRui2Z6E8WMysV2Lej3ev3euXd+vJdvnoLhzdPtOvBqraOVJ9ad 32 | idew/WBUZFhPR0WG9YhUZDSYk4qUNoalIrbZxBwu651hlSPzlfz9/UcQlMIrAzpajwce80zBFHCx 33 | UoSB/zF6k3tuCK0vzKk6CRndmex7A/+tV6PYb9xgPXdvZ4HejY//sDKPqqtwgbJ3twhbS1uErW0t 34 | wg00LeJt+FnMa13MrTCVYg43fqEThGHLzeIYjxnRVb2Adj4BK6HHOWe61uEKjmE31lWcCj6DdUO3 35 | 789/tzazUXoSAAA= 36 | headers: 37 | Access-Control-Allow-Origin: 38 | - '*' 39 | Access-Control-Expose-Headers: 40 | - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, 41 | X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, 42 | X-GitHub-Media-Type 43 | Cache-Control: 44 | - private, max-age=60, s-maxage=60 45 | Content-Encoding: 46 | - gzip 47 | Content-Security-Policy: 48 | - default-src 'none' 49 | Content-Type: 50 | - application/json; charset=utf-8 51 | Date: 52 | - Tue, 10 Sep 2019 16:53:18 GMT 53 | ETag: 54 | - W/"f6153453e8455ef3f55031d134f82d15" 55 | Referrer-Policy: 56 | - origin-when-cross-origin, strict-origin-when-cross-origin 57 | Server: 58 | - GitHub.com 59 | Status: 60 | - 200 OK 61 | Strict-Transport-Security: 62 | - max-age=31536000; includeSubdomains; preload 63 | Transfer-Encoding: 64 | - chunked 65 | Vary: 66 | - Accept, Authorization, Cookie, X-GitHub-OTP 67 | - Accept-Encoding 68 | X-Accepted-OAuth-Scopes: 69 | - admin:org, read:org, repo, user, write:org 70 | X-Content-Type-Options: 71 | - nosniff 72 | X-Frame-Options: 73 | - deny 74 | X-GitHub-Media-Type: 75 | - github.v3; format=json 76 | X-GitHub-Request-Id: 77 | - F0C5:5348:6E18E6:81DC8B:5D77D4FE 78 | X-OAuth-Scopes: 79 | - admin:org, admin:repo_hook, delete_repo, notifications, read:packages, repo, 80 | write:discussion, write:packages 81 | X-RateLimit-Limit: 82 | - '5000' 83 | X-RateLimit-Remaining: 84 | - '4999' 85 | X-RateLimit-Reset: 86 | - '1568137998' 87 | X-XSS-Protection: 88 | - 1; mode=block 89 | status: 90 | code: 200 91 | message: OK 92 | - request: 93 | body: null 94 | headers: 95 | Accept: 96 | - '*/*' 97 | Accept-Encoding: 98 | - gzip, deflate 99 | Connection: 100 | - keep-alive 101 | User-Agent: 102 | - PyGithub/Python 103 | authorization: 104 | - DUMMY 105 | method: GET 106 | uri: https://api.github.com/user 107 | response: 108 | body: 109 | string: !!binary | 110 | H4sIAAAAAAAAA52UXW/aMBiF/0rkayAfa9kSqWqrVbuYxLSpdJp6g4xjEiPHjvwBoqj/fccJg8LF 111 | pHCVxH7P48Pr97AnUldCkYK8WeebShuuyIiIkhSf8ixJRkTpki/CN5k9/Zr+/vNDsvXsdrZ+3KKO 112 | bqijZuGNxH7tXGuLOO4XbTqphKv90ltumFaOKzdhuol93JHvN3c3IFTmwOiOwMIFqxUHTK8Fy8Zn 113 | VmvXyAsD/bmd4Kx0paXUWxAuDf//kPiog73+XajqKgZ0+1i7mqNn+CnvoQHCuqGGOs0+Dg9cTaBY 114 | XIPh5UBTBxUsbRXc7GPDW93h/NIyI1ontBpq7kwLljYVVeKNXsOC1gIRbA210Wmg5RsM3lBxL9rH 115 | rREbynahJYYzLjZo8VXACzV4btdyTPwLxiA0XDi+oGUTorii0nIEjzah4Jmbkppofgon5rqlaoe9 116 | B1ygWmlTrrU3ikphG7CWiHSfJalZ1/aAoSr6ZqhiwjI9ir4+htY0VITgnkLyUIWlkBxs18JwupQw 117 | obyU4AqN4ickPjqdF0nOnDfcRPARYbKj54On6PvRVPTTaAS9mYDa+qUUbNFfT3Hz+bjSDTUpsvxf 118 | yBBUUuTTD5nDJ3YZbDlcBHWwg3+SL+M0Gyf5PEmLbFokyStO8W35sSbNxyjL0nmWFOltkaav5P0v 119 | yD0ixvsEAAA= 120 | headers: 121 | Access-Control-Allow-Origin: 122 | - '*' 123 | Access-Control-Expose-Headers: 124 | - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, 125 | X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, 126 | X-GitHub-Media-Type 127 | Cache-Control: 128 | - private, max-age=60, s-maxage=60 129 | Content-Encoding: 130 | - gzip 131 | Content-Security-Policy: 132 | - default-src 'none' 133 | Content-Type: 134 | - application/json; charset=utf-8 135 | Date: 136 | - Tue, 10 Sep 2019 16:53:18 GMT 137 | ETag: 138 | - W/"566ed2d612496c35fdf0e7114d906425" 139 | Last-Modified: 140 | - Wed, 21 Aug 2019 20:15:11 GMT 141 | Referrer-Policy: 142 | - origin-when-cross-origin, strict-origin-when-cross-origin 143 | Server: 144 | - GitHub.com 145 | Status: 146 | - 200 OK 147 | Strict-Transport-Security: 148 | - max-age=31536000; includeSubdomains; preload 149 | Transfer-Encoding: 150 | - chunked 151 | Vary: 152 | - Accept, Authorization, Cookie, X-GitHub-OTP 153 | - Accept-Encoding 154 | X-Accepted-OAuth-Scopes: 155 | - '' 156 | X-Content-Type-Options: 157 | - nosniff 158 | X-Frame-Options: 159 | - deny 160 | X-GitHub-Media-Type: 161 | - github.v3; format=json 162 | X-GitHub-Request-Id: 163 | - F0C5:5348:6E18F7:81DC9C:5D77D4FE 164 | X-OAuth-Scopes: 165 | - admin:org, admin:repo_hook, delete_repo, notifications, read:packages, repo, 166 | write:discussion, write:packages 167 | X-RateLimit-Limit: 168 | - '5000' 169 | X-RateLimit-Remaining: 170 | - '4998' 171 | X-RateLimit-Reset: 172 | - '1568137998' 173 | X-XSS-Protection: 174 | - 1; mode=block 175 | status: 176 | code: 200 177 | message: OK 178 | - request: 179 | body: null 180 | headers: 181 | Accept: 182 | - '*/*' 183 | Accept-Encoding: 184 | - gzip, deflate 185 | Connection: 186 | - keep-alive 187 | User-Agent: 188 | - PyGithub/Python 189 | authorization: 190 | - DUMMY 191 | method: GET 192 | uri: https://api.github.com/search/repositories?q=fake-project%2Buser%3Azstumgoren 193 | response: 194 | body: 195 | string: !!binary | 196 | H4sIAAAAAAAAA6tWKskvScyJT84vzStRsjLQUcrMS87PLchJLUmNL0otLs0pKVaySkvMKU4FSpWk 197 | 5gJ50bG1AMhF9bc3AAAA 198 | headers: 199 | Access-Control-Allow-Origin: 200 | - '*' 201 | Access-Control-Expose-Headers: 202 | - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, 203 | X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, 204 | X-GitHub-Media-Type 205 | Cache-Control: 206 | - no-cache 207 | Content-Encoding: 208 | - gzip 209 | Content-Security-Policy: 210 | - default-src 'none' 211 | Content-Type: 212 | - application/json; charset=utf-8 213 | Date: 214 | - Tue, 10 Sep 2019 16:53:19 GMT 215 | Referrer-Policy: 216 | - origin-when-cross-origin, strict-origin-when-cross-origin 217 | Server: 218 | - GitHub.com 219 | Status: 220 | - 200 OK 221 | Strict-Transport-Security: 222 | - max-age=31536000; includeSubdomains; preload 223 | Transfer-Encoding: 224 | - chunked 225 | Vary: 226 | - Accept-Encoding 227 | X-Accepted-OAuth-Scopes: 228 | - '' 229 | X-Content-Type-Options: 230 | - nosniff 231 | X-Frame-Options: 232 | - deny 233 | X-GitHub-Media-Type: 234 | - github.v3; format=json 235 | X-GitHub-Request-Id: 236 | - F0C6:7CF7:837B45:9B07AA:5D77D4FF 237 | X-OAuth-Scopes: 238 | - admin:org, admin:repo_hook, delete_repo, notifications, read:packages, repo, 239 | write:discussion, write:packages 240 | X-RateLimit-Limit: 241 | - '30' 242 | X-RateLimit-Remaining: 243 | - '29' 244 | X-RateLimit-Reset: 245 | - '1568134459' 246 | X-XSS-Protection: 247 | - 1; mode=block 248 | status: 249 | code: 200 250 | message: OK 251 | - request: 252 | body: '{"name": "fake-project", "private": true}' 253 | headers: 254 | Accept: 255 | - '*/*' 256 | Accept-Encoding: 257 | - gzip, deflate 258 | Connection: 259 | - keep-alive 260 | Content-Length: 261 | - '41' 262 | Content-Type: 263 | - application/json 264 | User-Agent: 265 | - PyGithub/Python 266 | authorization: 267 | - DUMMY 268 | method: POST 269 | uri: https://api.github.com/user/repos 270 | response: 271 | body: 272 | string: '{"id":207614484,"node_id":"MDEwOlJlcG9zaXRvcnkyMDc2MTQ0ODQ=","name":"fake-project","full_name":"zstumgoren/fake-project","private":true,"owner":{"login":"zstumgoren","id":39200,"node_id":"MDQ6VXNlcjM5MjAw","avatar_url":"https://avatars1.githubusercontent.com/u/39200?v=4","gravatar_id":"","url":"https://api.github.com/users/zstumgoren","html_url":"https://github.com/zstumgoren","followers_url":"https://api.github.com/users/zstumgoren/followers","following_url":"https://api.github.com/users/zstumgoren/following{/other_user}","gists_url":"https://api.github.com/users/zstumgoren/gists{/gist_id}","starred_url":"https://api.github.com/users/zstumgoren/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zstumgoren/subscriptions","organizations_url":"https://api.github.com/users/zstumgoren/orgs","repos_url":"https://api.github.com/users/zstumgoren/repos","events_url":"https://api.github.com/users/zstumgoren/events{/privacy}","received_events_url":"https://api.github.com/users/zstumgoren/received_events","type":"User","site_admin":false},"html_url":"https://github.com/zstumgoren/fake-project","description":null,"fork":false,"url":"https://api.github.com/repos/zstumgoren/fake-project","forks_url":"https://api.github.com/repos/zstumgoren/fake-project/forks","keys_url":"https://api.github.com/repos/zstumgoren/fake-project/keys{/key_id}","collaborators_url":"https://api.github.com/repos/zstumgoren/fake-project/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/zstumgoren/fake-project/teams","hooks_url":"https://api.github.com/repos/zstumgoren/fake-project/hooks","issue_events_url":"https://api.github.com/repos/zstumgoren/fake-project/issues/events{/number}","events_url":"https://api.github.com/repos/zstumgoren/fake-project/events","assignees_url":"https://api.github.com/repos/zstumgoren/fake-project/assignees{/user}","branches_url":"https://api.github.com/repos/zstumgoren/fake-project/branches{/branch}","tags_url":"https://api.github.com/repos/zstumgoren/fake-project/tags","blobs_url":"https://api.github.com/repos/zstumgoren/fake-project/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/zstumgoren/fake-project/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/zstumgoren/fake-project/git/refs{/sha}","trees_url":"https://api.github.com/repos/zstumgoren/fake-project/git/trees{/sha}","statuses_url":"https://api.github.com/repos/zstumgoren/fake-project/statuses/{sha}","languages_url":"https://api.github.com/repos/zstumgoren/fake-project/languages","stargazers_url":"https://api.github.com/repos/zstumgoren/fake-project/stargazers","contributors_url":"https://api.github.com/repos/zstumgoren/fake-project/contributors","subscribers_url":"https://api.github.com/repos/zstumgoren/fake-project/subscribers","subscription_url":"https://api.github.com/repos/zstumgoren/fake-project/subscription","commits_url":"https://api.github.com/repos/zstumgoren/fake-project/commits{/sha}","git_commits_url":"https://api.github.com/repos/zstumgoren/fake-project/git/commits{/sha}","comments_url":"https://api.github.com/repos/zstumgoren/fake-project/comments{/number}","issue_comment_url":"https://api.github.com/repos/zstumgoren/fake-project/issues/comments{/number}","contents_url":"https://api.github.com/repos/zstumgoren/fake-project/contents/{+path}","compare_url":"https://api.github.com/repos/zstumgoren/fake-project/compare/{base}...{head}","merges_url":"https://api.github.com/repos/zstumgoren/fake-project/merges","archive_url":"https://api.github.com/repos/zstumgoren/fake-project/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/zstumgoren/fake-project/downloads","issues_url":"https://api.github.com/repos/zstumgoren/fake-project/issues{/number}","pulls_url":"https://api.github.com/repos/zstumgoren/fake-project/pulls{/number}","milestones_url":"https://api.github.com/repos/zstumgoren/fake-project/milestones{/number}","notifications_url":"https://api.github.com/repos/zstumgoren/fake-project/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/zstumgoren/fake-project/labels{/name}","releases_url":"https://api.github.com/repos/zstumgoren/fake-project/releases{/id}","deployments_url":"https://api.github.com/repos/zstumgoren/fake-project/deployments","created_at":"2019-09-10T16:53:19Z","updated_at":"2019-09-10T16:53:19Z","pushed_at":"2019-09-10T16:53:20Z","git_url":"git://github.com/zstumgoren/fake-project.git","ssh_url":"git@github.com:zstumgoren/fake-project.git","clone_url":"https://github.com/zstumgoren/fake-project.git","svn_url":"https://github.com/zstumgoren/fake-project","homepage":null,"size":0,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":0,"license":null,"forks":0,"open_issues":0,"watchers":0,"default_branch":"main","permissions":{"admin":true,"push":true,"pull":true},"allow_squash_merge":true,"allow_merge_commit":true,"allow_rebase_merge":true,"network_count":0,"subscribers_count":1}' 273 | headers: 274 | Access-Control-Allow-Origin: 275 | - '*' 276 | Access-Control-Expose-Headers: 277 | - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, 278 | X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, 279 | X-GitHub-Media-Type 280 | Cache-Control: 281 | - private, max-age=60, s-maxage=60 282 | Content-Length: 283 | - '5146' 284 | Content-Security-Policy: 285 | - default-src 'none' 286 | Content-Type: 287 | - application/json; charset=utf-8 288 | Date: 289 | - Tue, 10 Sep 2019 16:53:20 GMT 290 | ETag: 291 | - '"a8373c57e3ed35b94942a5e55c20314d"' 292 | Location: 293 | - https://api.github.com/repos/zstumgoren/fake-project 294 | Referrer-Policy: 295 | - origin-when-cross-origin, strict-origin-when-cross-origin 296 | Server: 297 | - GitHub.com 298 | Status: 299 | - 201 Created 300 | Strict-Transport-Security: 301 | - max-age=31536000; includeSubdomains; preload 302 | Vary: 303 | - Accept, Authorization, Cookie, X-GitHub-OTP 304 | - Accept-Encoding 305 | X-Accepted-OAuth-Scopes: 306 | - public_repo, repo 307 | X-Content-Type-Options: 308 | - nosniff 309 | X-Frame-Options: 310 | - deny 311 | X-GitHub-Media-Type: 312 | - github.v3; format=json 313 | X-GitHub-Request-Id: 314 | - F0C5:5348:6E1929:81DCAE:5D77D4FE 315 | X-OAuth-Scopes: 316 | - admin:org, admin:repo_hook, delete_repo, notifications, read:packages, repo, 317 | write:discussion, write:packages 318 | X-RateLimit-Limit: 319 | - '5000' 320 | X-RateLimit-Remaining: 321 | - '4997' 322 | X-RateLimit-Reset: 323 | - '1568137998' 324 | X-XSS-Protection: 325 | - 1; mode=block 326 | status: 327 | code: 201 328 | message: Created 329 | version: 1 330 | -------------------------------------------------------------------------------- /tests/commands/cassettes/test_choose_default_account_basic.yaml: -------------------------------------------------------------------------------- 1 | interactions: 2 | - request: 3 | body: null 4 | headers: 5 | Accept: 6 | - '*/*' 7 | Accept-Encoding: 8 | - gzip, deflate 9 | Connection: 10 | - keep-alive 11 | User-Agent: 12 | - PyGithub/Python 13 | authorization: 14 | - DUMMY 15 | method: GET 16 | uri: https://api.github.com/user/orgs 17 | response: 18 | body: 19 | string: '[]' 20 | headers: 21 | Access-Control-Allow-Origin: 22 | - '*' 23 | Access-Control-Expose-Headers: 24 | - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, 25 | X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, 26 | X-GitHub-Media-Type 27 | Cache-Control: 28 | - private, max-age=60, s-maxage=60 29 | Content-Length: 30 | - '2' 31 | Content-Security-Policy: 32 | - default-src 'none' 33 | Content-Type: 34 | - application/json; charset=utf-8 35 | Date: 36 | - Thu, 03 Oct 2019 21:48:11 GMT 37 | ETag: 38 | - '"40c720907082566afcff28c6fd9d529d"' 39 | Referrer-Policy: 40 | - origin-when-cross-origin, strict-origin-when-cross-origin 41 | Server: 42 | - GitHub.com 43 | Status: 44 | - 200 OK 45 | Strict-Transport-Security: 46 | - max-age=31536000; includeSubdomains; preload 47 | Vary: 48 | - Accept, Authorization, Cookie, X-GitHub-OTP 49 | - Accept-Encoding 50 | X-Accepted-OAuth-Scopes: 51 | - admin:org, read:org, repo, user, write:org 52 | X-Content-Type-Options: 53 | - nosniff 54 | X-Frame-Options: 55 | - deny 56 | X-GitHub-Media-Type: 57 | - github.v3; format=json 58 | X-GitHub-Request-Id: 59 | - CB8F:9576:6C521F:81B0EF:5D966C9B 60 | X-OAuth-Scopes: 61 | - repo 62 | X-RateLimit-Limit: 63 | - '5000' 64 | X-RateLimit-Remaining: 65 | - '4998' 66 | X-RateLimit-Reset: 67 | - '1570142726' 68 | X-XSS-Protection: 69 | - 1; mode=block 70 | status: 71 | code: 200 72 | message: OK 73 | - request: 74 | body: null 75 | headers: 76 | Accept: 77 | - '*/*' 78 | Accept-Encoding: 79 | - gzip, deflate 80 | Connection: 81 | - keep-alive 82 | User-Agent: 83 | - PyGithub/Python 84 | authorization: 85 | - DUMMY 86 | method: GET 87 | uri: https://api.github.com/user 88 | response: 89 | body: 90 | string: !!binary | 91 | H4sIAAAAAAAAA52TTWvjMBCG/4vOSeSPTcMall56TaHQLEsvQZYVe1pZEtLYJWv633dkJy0JhcU5 92 | 2RrN++jVaGZg2tZgWMGqN8AlqoDKswWDihXruyTfZOvNghlbqX0Mse3D093vP49avu6y7cM2377u 93 | ckoXvUDh953XlNMgulBwPgVDuqoBm67sgvLSGlQGV9K2vOPnA+77Xz8IUvsTZjyJAlc4ByfSJCdc 94 | 4JeuG2z1lYnp7FFxmXuwWtt3Yly7/s8x/FNIDqd/MPVtEBIO3GKjqHR0nY9YBAg429IoGnj80DNF 95 | TKDn8Kqaa+skI1PvhvwM3CtnR15XBunBIVgz296FmGDW18LAX3ETjMSBGNHYbCOjiMSqpyacrZ5U 96 | A3ceeiGPsSxeSQU91fk24pWcgHh0ipp/R90Qqw6o9qJq44AehA6KRlG0lGA6rReMmtoJczwvSxrl 97 | aXC0lWNxzzuqFUCTOaka8EqU+pNSgj1vua7UIPdTmYpkwU6Bsb9YDHw1/9eKunjck8RFqoVAcpEl 98 | 6c9lmiyT9DldF0leZOsXulHnqm9y8ucsLfKkSDcv7OMfekQVLZMEAAA= 99 | headers: 100 | Access-Control-Allow-Origin: 101 | - '*' 102 | Access-Control-Expose-Headers: 103 | - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, 104 | X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, 105 | X-GitHub-Media-Type 106 | Cache-Control: 107 | - private, max-age=60, s-maxage=60 108 | Content-Encoding: 109 | - gzip 110 | Content-Security-Policy: 111 | - default-src 'none' 112 | Content-Type: 113 | - application/json; charset=utf-8 114 | Date: 115 | - Thu, 03 Oct 2019 21:48:11 GMT 116 | ETag: 117 | - W/"dbf112e2419f6c409b797ce2cf2a1251" 118 | Last-Modified: 119 | - Thu, 03 Oct 2019 21:30:17 GMT 120 | Referrer-Policy: 121 | - origin-when-cross-origin, strict-origin-when-cross-origin 122 | Server: 123 | - GitHub.com 124 | Status: 125 | - 200 OK 126 | Strict-Transport-Security: 127 | - max-age=31536000; includeSubdomains; preload 128 | Transfer-Encoding: 129 | - chunked 130 | Vary: 131 | - Accept, Authorization, Cookie, X-GitHub-OTP 132 | - Accept-Encoding 133 | X-Accepted-OAuth-Scopes: 134 | - '' 135 | X-Content-Type-Options: 136 | - nosniff 137 | X-Frame-Options: 138 | - deny 139 | X-GitHub-Media-Type: 140 | - github.v3; format=json 141 | X-GitHub-Request-Id: 142 | - CB8F:9576:6C5229:81B0F8:5D966C9B 143 | X-OAuth-Scopes: 144 | - repo 145 | X-RateLimit-Limit: 146 | - '5000' 147 | X-RateLimit-Remaining: 148 | - '4997' 149 | X-RateLimit-Reset: 150 | - '1570142726' 151 | X-XSS-Protection: 152 | - 1; mode=block 153 | status: 154 | code: 200 155 | message: OK 156 | - request: 157 | body: '{"name": "fake-project", "private": true}' 158 | headers: 159 | Accept: 160 | - '*/*' 161 | Accept-Encoding: 162 | - gzip, deflate 163 | Connection: 164 | - keep-alive 165 | Content-Length: 166 | - '41' 167 | Content-Type: 168 | - application/json 169 | User-Agent: 170 | - PyGithub/Python 171 | authorization: 172 | - DUMMY 173 | method: POST 174 | uri: https://api.github.com/user/repos 175 | response: 176 | body: 177 | string: '{"id":212687008,"node_id":"MDEwOlJlcG9zaXRvcnkyMTI2ODcwMDg=","name":"fake-project","full_name":"dkit-tester/fake-project","private":true,"owner":{"login":"dkit-tester","id":56037257,"node_id":"MDQ6VXNlcjU2MDM3MjU3","avatar_url":"https://avatars1.githubusercontent.com/u/56037257?v=4","gravatar_id":"","url":"https://api.github.com/users/dkit-tester","html_url":"https://github.com/dkit-tester","followers_url":"https://api.github.com/users/dkit-tester/followers","following_url":"https://api.github.com/users/dkit-tester/following{/other_user}","gists_url":"https://api.github.com/users/dkit-tester/gists{/gist_id}","starred_url":"https://api.github.com/users/dkit-tester/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dkit-tester/subscriptions","organizations_url":"https://api.github.com/users/dkit-tester/orgs","repos_url":"https://api.github.com/users/dkit-tester/repos","events_url":"https://api.github.com/users/dkit-tester/events{/privacy}","received_events_url":"https://api.github.com/users/dkit-tester/received_events","type":"User","site_admin":false},"html_url":"https://github.com/dkit-tester/fake-project","description":null,"fork":false,"url":"https://api.github.com/repos/dkit-tester/fake-project","forks_url":"https://api.github.com/repos/dkit-tester/fake-project/forks","keys_url":"https://api.github.com/repos/dkit-tester/fake-project/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dkit-tester/fake-project/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dkit-tester/fake-project/teams","hooks_url":"https://api.github.com/repos/dkit-tester/fake-project/hooks","issue_events_url":"https://api.github.com/repos/dkit-tester/fake-project/issues/events{/number}","events_url":"https://api.github.com/repos/dkit-tester/fake-project/events","assignees_url":"https://api.github.com/repos/dkit-tester/fake-project/assignees{/user}","branches_url":"https://api.github.com/repos/dkit-tester/fake-project/branches{/branch}","tags_url":"https://api.github.com/repos/dkit-tester/fake-project/tags","blobs_url":"https://api.github.com/repos/dkit-tester/fake-project/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dkit-tester/fake-project/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dkit-tester/fake-project/git/refs{/sha}","trees_url":"https://api.github.com/repos/dkit-tester/fake-project/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dkit-tester/fake-project/statuses/{sha}","languages_url":"https://api.github.com/repos/dkit-tester/fake-project/languages","stargazers_url":"https://api.github.com/repos/dkit-tester/fake-project/stargazers","contributors_url":"https://api.github.com/repos/dkit-tester/fake-project/contributors","subscribers_url":"https://api.github.com/repos/dkit-tester/fake-project/subscribers","subscription_url":"https://api.github.com/repos/dkit-tester/fake-project/subscription","commits_url":"https://api.github.com/repos/dkit-tester/fake-project/commits{/sha}","git_commits_url":"https://api.github.com/repos/dkit-tester/fake-project/git/commits{/sha}","comments_url":"https://api.github.com/repos/dkit-tester/fake-project/comments{/number}","issue_comment_url":"https://api.github.com/repos/dkit-tester/fake-project/issues/comments{/number}","contents_url":"https://api.github.com/repos/dkit-tester/fake-project/contents/{+path}","compare_url":"https://api.github.com/repos/dkit-tester/fake-project/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dkit-tester/fake-project/merges","archive_url":"https://api.github.com/repos/dkit-tester/fake-project/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dkit-tester/fake-project/downloads","issues_url":"https://api.github.com/repos/dkit-tester/fake-project/issues{/number}","pulls_url":"https://api.github.com/repos/dkit-tester/fake-project/pulls{/number}","milestones_url":"https://api.github.com/repos/dkit-tester/fake-project/milestones{/number}","notifications_url":"https://api.github.com/repos/dkit-tester/fake-project/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dkit-tester/fake-project/labels{/name}","releases_url":"https://api.github.com/repos/dkit-tester/fake-project/releases{/id}","deployments_url":"https://api.github.com/repos/dkit-tester/fake-project/deployments","created_at":"2019-10-03T21:48:12Z","updated_at":"2019-10-03T21:48:12Z","pushed_at":"2019-10-03T21:48:12Z","git_url":"git://github.com/dkit-tester/fake-project.git","ssh_url":"git@github.com:dkit-tester/fake-project.git","clone_url":"https://github.com/dkit-tester/fake-project.git","svn_url":"https://github.com/dkit-tester/fake-project","homepage":null,"size":0,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":0,"license":null,"forks":0,"open_issues":0,"watchers":0,"default_branch":"main","permissions":{"admin":true,"push":true,"pull":true},"allow_squash_merge":true,"allow_merge_commit":true,"allow_rebase_merge":true,"network_count":0,"subscribers_count":1}' 178 | headers: 179 | Access-Control-Allow-Origin: 180 | - '*' 181 | Access-Control-Expose-Headers: 182 | - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, 183 | X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, 184 | X-GitHub-Media-Type 185 | Cache-Control: 186 | - private, max-age=60, s-maxage=60 187 | Content-Length: 188 | - '5211' 189 | Content-Security-Policy: 190 | - default-src 'none' 191 | Content-Type: 192 | - application/json; charset=utf-8 193 | Date: 194 | - Thu, 03 Oct 2019 21:48:12 GMT 195 | ETag: 196 | - '"8c2c989ff57e6c3856d248479358984b"' 197 | Location: 198 | - https://api.github.com/repos/dkit-tester/fake-project 199 | Referrer-Policy: 200 | - origin-when-cross-origin, strict-origin-when-cross-origin 201 | Server: 202 | - GitHub.com 203 | Status: 204 | - 201 Created 205 | Strict-Transport-Security: 206 | - max-age=31536000; includeSubdomains; preload 207 | Vary: 208 | - Accept, Authorization, Cookie, X-GitHub-OTP 209 | - Accept-Encoding 210 | X-Accepted-OAuth-Scopes: 211 | - public_repo, repo 212 | X-Content-Type-Options: 213 | - nosniff 214 | X-Frame-Options: 215 | - deny 216 | X-GitHub-Media-Type: 217 | - github.v3; format=json 218 | X-GitHub-Request-Id: 219 | - CB8F:9576:6C5232:81B101:5D966C9B 220 | X-OAuth-Scopes: 221 | - repo 222 | X-RateLimit-Limit: 223 | - '5000' 224 | X-RateLimit-Remaining: 225 | - '4996' 226 | X-RateLimit-Reset: 227 | - '1570142726' 228 | X-XSS-Protection: 229 | - 1; mode=block 230 | status: 231 | code: 201 232 | message: Created 233 | version: 1 234 | -------------------------------------------------------------------------------- /tests/commands/cassettes/test_choose_org_account_private_error.yaml: -------------------------------------------------------------------------------- 1 | interactions: 2 | - request: 3 | body: null 4 | headers: 5 | Accept: 6 | - '*/*' 7 | Accept-Encoding: 8 | - gzip, deflate 9 | Connection: 10 | - keep-alive 11 | User-Agent: 12 | - PyGithub/Python 13 | authorization: 14 | - DUMMY 15 | method: GET 16 | uri: https://api.github.com/user/orgs 17 | response: 18 | body: 19 | string: !!binary | 20 | H4sIAAAAAAAAA62X7WrbMBSGb0X479Imjuu1KZQxSDc6cLuyho2NURRbcZQolpHkdEkp7DZ2e7uS 21 | HTkfs1yHWMb/GuPnVaif8/rkx7PDeEwT59KJeJgtSKJCxrPI6Tg0ci4HnnfhdZyER+RRf3aC4fXq 22 | bj5Yfe9/yPC3dBp9ZMvxbL4O1vEamEwwuGmqVCovu12c0tOYqmk2Pg35ostFLLvlUwRJuXy05Lo5 23 | BeeRJXxhe3yDAT/lfG6P55T+D0mZEXt8gwG/IIsxEfYBW+65u/njBaLSbMxo+Ng00cSLwXiJFRbl 24 | B5RflP3t080kESFPFDyL/EFn3dybd8urM/hqEZGhoKmiXFvmvHT+K/d5paY8+cQzkeSPUyvme97Z 25 | ef+4cyNw7t4L4qsrAI/7Uz6qrncGZ++diVt7Z+LW3pl4A+/MgDa8MxPb9m4jT5V4ScZYUT2+JGJJ 26 | ydPWugv/zPPd49bF7u0wcIP7mtYVTqkr3A6xd21PWmu2J60N25MN5NqzbXi1D2umVO9glW3MqFLK 27 | eZgSxFOSIAkNFhK0e7ehBU1oEqOUYTXhYmF0HpaShxQrEqWCyF3rue5bf+D2jgt4/et2NvKDh/f1 28 | au/1aXU9LJH2OpYDrK0sB1jLWQ5o4Gg5og1Vy5nNjHUPGrt1qVJZQ0XtLmEk1K/mvYiDnj8Y1BHR 29 | D4Yj/66uiOWz6mpocPYSmri1giZuLaCJN9DPDGhDPjOxmXqH9z53Y0+lerotY44Z4hN0B+Zd78xD 30 | VCLFUSgItCJScNuECqnQRBDSQbBQQlFOSSLpEj5KhZMIi4iuSdRBjCZzEiFJlE7duYygWDOmJIpg 31 | TUXQwHnoKKFQuuiLglPkqTEIOhRui2Z6E8WMysV2Lej3ev3euXd+vJdvnoLhzdPtOvBqraOVJ9ad 32 | idew/WBUZFhPR0WG9YhUZDSYk4qUNoalIrbZxBwu651hlSPzlfz9/UcQlMIrAzpajwce80zBFHCx 33 | UoSB/zF6k3tuCK0vzKk6CRndmex7A/+tV6PYb9xgPXdvZ4HejY//sDKPqqtwgbJ3twhbS1uErW0t 34 | wg00LeJt+FnMa13MrTCVYg43fqEThGHLzeIYjxnRVb2Adj4BK6HHOWe61uEKjmE31lWcCj6DdUO3 35 | 789/tzazUXoSAAA= 36 | headers: 37 | Access-Control-Allow-Origin: 38 | - '*' 39 | Access-Control-Expose-Headers: 40 | - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, 41 | X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, 42 | X-GitHub-Media-Type 43 | Cache-Control: 44 | - private, max-age=60, s-maxage=60 45 | Content-Encoding: 46 | - gzip 47 | Content-Security-Policy: 48 | - default-src 'none' 49 | Content-Type: 50 | - application/json; charset=utf-8 51 | Date: 52 | - Tue, 10 Sep 2019 18:37:14 GMT 53 | ETag: 54 | - W/"f6153453e8455ef3f55031d134f82d15" 55 | Referrer-Policy: 56 | - origin-when-cross-origin, strict-origin-when-cross-origin 57 | Server: 58 | - GitHub.com 59 | Status: 60 | - 200 OK 61 | Strict-Transport-Security: 62 | - max-age=31536000; includeSubdomains; preload 63 | Transfer-Encoding: 64 | - chunked 65 | Vary: 66 | - Accept, Authorization, Cookie, X-GitHub-OTP 67 | - Accept-Encoding 68 | X-Accepted-OAuth-Scopes: 69 | - admin:org, read:org, repo, user, write:org 70 | X-Content-Type-Options: 71 | - nosniff 72 | X-Frame-Options: 73 | - deny 74 | X-GitHub-Media-Type: 75 | - github.v3; format=json 76 | X-GitHub-Request-Id: 77 | - F4A4:4203:33EB70:3DA9CA:5D77ED5A 78 | X-OAuth-Scopes: 79 | - admin:org, admin:repo_hook, delete_repo, notifications, read:packages, repo, 80 | write:discussion, write:packages 81 | X-RateLimit-Limit: 82 | - '5000' 83 | X-RateLimit-Remaining: 84 | - '4987' 85 | X-RateLimit-Reset: 86 | - '1568144234' 87 | X-XSS-Protection: 88 | - 1; mode=block 89 | status: 90 | code: 200 91 | message: OK 92 | - request: 93 | body: null 94 | headers: 95 | Accept: 96 | - '*/*' 97 | Accept-Encoding: 98 | - gzip, deflate 99 | Connection: 100 | - keep-alive 101 | User-Agent: 102 | - PyGithub/Python 103 | authorization: 104 | - DUMMY 105 | method: GET 106 | uri: https://api.github.com/user 107 | response: 108 | body: 109 | string: !!binary | 110 | H4sIAAAAAAAAA52UXW/aMBiF/0rkayAfa9kSqWqrVbuYxLSpdJp6g4xjEiPHjvwBoqj/fccJg8LF 111 | pHCVxH7P48Pr97AnUldCkYK8WeebShuuyIiIkhSf8ixJRkTpki/CN5k9/Zr+/vNDsvXsdrZ+3KKO 112 | bqijZuGNxH7tXGuLOO4XbTqphKv90ltumFaOKzdhuol93JHvN3c3IFTmwOiOwMIFqxUHTK8Fy8Zn 113 | VmvXyAsD/bmd4Kx0paXUWxAuDf//kPiog73+XajqKgZ0+1i7mqNn+CnvoQHCuqGGOs0+Dg9cTaBY 114 | XIPh5UBTBxUsbRXc7GPDW93h/NIyI1ontBpq7kwLljYVVeKNXsOC1gIRbA210Wmg5RsM3lBxL9rH 115 | rREbynahJYYzLjZo8VXACzV4btdyTPwLxiA0XDi+oGUTorii0nIEjzah4Jmbkppofgon5rqlaoe9 116 | B1ygWmlTrrU3ikphG7CWiHSfJalZ1/aAoSr6ZqhiwjI9ir4+htY0VITgnkLyUIWlkBxs18JwupQw 117 | obyU4AqN4ickPjqdF0nOnDfcRPARYbKj54On6PvRVPTTaAS9mYDa+qUUbNFfT3Hz+bjSDTUpsvxf 118 | yBBUUuTTD5nDJ3YZbDlcBHWwg3+SL+M0Gyf5PEmLbFokyStO8W35sSbNxyjL0nmWFOltkaav5P0v 119 | yD0ixvsEAAA= 120 | headers: 121 | Access-Control-Allow-Origin: 122 | - '*' 123 | Access-Control-Expose-Headers: 124 | - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, 125 | X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, 126 | X-GitHub-Media-Type 127 | Cache-Control: 128 | - private, max-age=60, s-maxage=60 129 | Content-Encoding: 130 | - gzip 131 | Content-Security-Policy: 132 | - default-src 'none' 133 | Content-Type: 134 | - application/json; charset=utf-8 135 | Date: 136 | - Tue, 10 Sep 2019 18:37:14 GMT 137 | ETag: 138 | - W/"566ed2d612496c35fdf0e7114d906425" 139 | Last-Modified: 140 | - Wed, 21 Aug 2019 20:15:11 GMT 141 | Referrer-Policy: 142 | - origin-when-cross-origin, strict-origin-when-cross-origin 143 | Server: 144 | - GitHub.com 145 | Status: 146 | - 200 OK 147 | Strict-Transport-Security: 148 | - max-age=31536000; includeSubdomains; preload 149 | Transfer-Encoding: 150 | - chunked 151 | Vary: 152 | - Accept, Authorization, Cookie, X-GitHub-OTP 153 | - Accept-Encoding 154 | X-Accepted-OAuth-Scopes: 155 | - '' 156 | X-Content-Type-Options: 157 | - nosniff 158 | X-Frame-Options: 159 | - deny 160 | X-GitHub-Media-Type: 161 | - github.v3; format=json 162 | X-GitHub-Request-Id: 163 | - F4A4:4203:33EB73:3DA9D2:5D77ED5A 164 | X-OAuth-Scopes: 165 | - admin:org, admin:repo_hook, delete_repo, notifications, read:packages, repo, 166 | write:discussion, write:packages 167 | X-RateLimit-Limit: 168 | - '5000' 169 | X-RateLimit-Remaining: 170 | - '4986' 171 | X-RateLimit-Reset: 172 | - '1568144234' 173 | X-XSS-Protection: 174 | - 1; mode=block 175 | status: 176 | code: 200 177 | message: OK 178 | - request: 179 | body: '{"name": "fake-project", "private": true}' 180 | headers: 181 | Accept: 182 | - '*/*' 183 | Accept-Encoding: 184 | - gzip, deflate 185 | Connection: 186 | - keep-alive 187 | Content-Length: 188 | - '41' 189 | Content-Type: 190 | - application/json 191 | User-Agent: 192 | - PyGithub/Python 193 | authorization: 194 | - DUMMY 195 | method: POST 196 | uri: https://api.github.com/orgs/associatedpress/repos 197 | response: 198 | body: 199 | string: '{"message":"Visibility can''t be private. Please upgrade your subscription 200 | to create a new private repository.","documentation_url":"https://github.com/pricing"}' 201 | headers: 202 | Access-Control-Allow-Origin: 203 | - '*' 204 | Access-Control-Expose-Headers: 205 | - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, 206 | X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, 207 | X-GitHub-Media-Type 208 | Content-Length: 209 | - '160' 210 | Content-Security-Policy: 211 | - default-src 'none' 212 | Content-Type: 213 | - application/json; charset=utf-8 214 | Date: 215 | - Tue, 10 Sep 2019 18:37:14 GMT 216 | Referrer-Policy: 217 | - origin-when-cross-origin, strict-origin-when-cross-origin 218 | Server: 219 | - GitHub.com 220 | Status: 221 | - 422 Unprocessable Entity 222 | Strict-Transport-Security: 223 | - max-age=31536000; includeSubdomains; preload 224 | X-Accepted-OAuth-Scopes: 225 | - public_repo, repo 226 | X-Content-Type-Options: 227 | - nosniff 228 | X-Frame-Options: 229 | - deny 230 | X-GitHub-Media-Type: 231 | - github.v3; format=json 232 | X-GitHub-Request-Id: 233 | - F4A4:4203:33EB7C:3DA9DC:5D77ED5A 234 | X-OAuth-Scopes: 235 | - admin:org, admin:repo_hook, delete_repo, notifications, read:packages, repo, 236 | write:discussion, write:packages 237 | X-RateLimit-Limit: 238 | - '5000' 239 | X-RateLimit-Remaining: 240 | - '4985' 241 | X-RateLimit-Reset: 242 | - '1568144234' 243 | X-XSS-Protection: 244 | - 1; mode=block 245 | status: 246 | code: 422 247 | message: Unprocessable Entity 248 | version: 1 249 | -------------------------------------------------------------------------------- /tests/commands/cassettes/test_choose_org_account_public_repo.yaml: -------------------------------------------------------------------------------- 1 | interactions: 2 | - request: 3 | body: null 4 | headers: 5 | Accept: 6 | - '*/*' 7 | Accept-Encoding: 8 | - gzip, deflate 9 | Connection: 10 | - keep-alive 11 | User-Agent: 12 | - PyGithub/Python 13 | authorization: 14 | - DUMMY 15 | method: GET 16 | uri: https://api.github.com/user/orgs 17 | response: 18 | body: 19 | string: !!binary | 20 | H4sIAAAAAAAAA62X7WrbMBSGb0X479Imjuu1KZQxSDc6cLuyho2NURRbcZQolpHkdEkp7DZ2e7uS 21 | HTkfs1yHWMb/GuPnVaif8/rkx7PDeEwT59KJeJgtSKJCxrPI6Tg0ci4HnnfhdZyER+RRf3aC4fXq 22 | bj5Yfe9/yPC3dBp9ZMvxbL4O1vEamEwwuGmqVCovu12c0tOYqmk2Pg35ostFLLvlUwRJuXy05Lo5 23 | BeeRJXxhe3yDAT/lfG6P55T+D0mZEXt8gwG/IIsxEfYBW+65u/njBaLSbMxo+Ng00cSLwXiJFRbl 24 | B5RflP3t080kESFPFDyL/EFn3dybd8urM/hqEZGhoKmiXFvmvHT+K/d5paY8+cQzkeSPUyvme97Z 25 | ef+4cyNw7t4L4qsrAI/7Uz6qrncGZ++diVt7Z+LW3pl4A+/MgDa8MxPb9m4jT5V4ScZYUT2+JGJJ 26 | ydPWugv/zPPd49bF7u0wcIP7mtYVTqkr3A6xd21PWmu2J60N25MN5NqzbXi1D2umVO9glW3MqFLK 27 | eZgSxFOSIAkNFhK0e7ehBU1oEqOUYTXhYmF0HpaShxQrEqWCyF3rue5bf+D2jgt4/et2NvKDh/f1 28 | au/1aXU9LJH2OpYDrK0sB1jLWQ5o4Gg5og1Vy5nNjHUPGrt1qVJZQ0XtLmEk1K/mvYiDnj8Y1BHR 29 | D4Yj/66uiOWz6mpocPYSmri1giZuLaCJN9DPDGhDPjOxmXqH9z53Y0+lerotY44Z4hN0B+Zd78xD 30 | VCLFUSgItCJScNuECqnQRBDSQbBQQlFOSSLpEj5KhZMIi4iuSdRBjCZzEiFJlE7duYygWDOmJIpg 31 | TUXQwHnoKKFQuuiLglPkqTEIOhRui2Z6E8WMysV2Lej3ev3euXd+vJdvnoLhzdPtOvBqraOVJ9ad 32 | idew/WBUZFhPR0WG9YhUZDSYk4qUNoalIrbZxBwu651hlSPzlfz9/UcQlMIrAzpajwce80zBFHCx 33 | UoSB/zF6k3tuCK0vzKk6CRndmex7A/+tV6PYb9xgPXdvZ4HejY//sDKPqqtwgbJ3twhbS1uErW0t 34 | wg00LeJt+FnMa13MrTCVYg43fqEThGHLzeIYjxnRVb2Adj4BK6HHOWe61uEKjmE31lWcCj6DdUO3 35 | 789/tzazUXoSAAA= 36 | headers: 37 | Access-Control-Allow-Origin: 38 | - '*' 39 | Access-Control-Expose-Headers: 40 | - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, 41 | X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, 42 | X-GitHub-Media-Type 43 | Cache-Control: 44 | - private, max-age=60, s-maxage=60 45 | Content-Encoding: 46 | - gzip 47 | Content-Security-Policy: 48 | - default-src 'none' 49 | Content-Type: 50 | - application/json; charset=utf-8 51 | Date: 52 | - Tue, 10 Sep 2019 18:44:26 GMT 53 | ETag: 54 | - W/"f6153453e8455ef3f55031d134f82d15" 55 | Referrer-Policy: 56 | - origin-when-cross-origin, strict-origin-when-cross-origin 57 | Server: 58 | - GitHub.com 59 | Status: 60 | - 200 OK 61 | Strict-Transport-Security: 62 | - max-age=31536000; includeSubdomains; preload 63 | Transfer-Encoding: 64 | - chunked 65 | Vary: 66 | - Accept, Authorization, Cookie, X-GitHub-OTP 67 | - Accept-Encoding 68 | X-Accepted-OAuth-Scopes: 69 | - admin:org, read:org, repo, user, write:org 70 | X-Content-Type-Options: 71 | - nosniff 72 | X-Frame-Options: 73 | - deny 74 | X-GitHub-Media-Type: 75 | - github.v3; format=json 76 | X-GitHub-Request-Id: 77 | - F4D8:4203:3438CC:3E04BA:5D77EF0A 78 | X-OAuth-Scopes: 79 | - admin:org, admin:repo_hook, delete_repo, notifications, read:packages, repo, 80 | write:discussion, write:packages 81 | X-RateLimit-Limit: 82 | - '5000' 83 | X-RateLimit-Remaining: 84 | - '4984' 85 | X-RateLimit-Reset: 86 | - '1568144666' 87 | X-XSS-Protection: 88 | - 1; mode=block 89 | status: 90 | code: 200 91 | message: OK 92 | - request: 93 | body: null 94 | headers: 95 | Accept: 96 | - '*/*' 97 | Accept-Encoding: 98 | - gzip, deflate 99 | Connection: 100 | - keep-alive 101 | User-Agent: 102 | - PyGithub/Python 103 | authorization: 104 | - DUMMY 105 | method: GET 106 | uri: https://api.github.com/user 107 | response: 108 | body: 109 | string: !!binary | 110 | H4sIAAAAAAAAA52UXW/aMBiF/0rkayAfa9kSqWqrVbuYxLSpdJp6g4xjEiPHjvwBoqj/fccJg8LF 111 | pHCVxH7P48Pr97AnUldCkYK8WeebShuuyIiIkhSf8ixJRkTpki/CN5k9/Zr+/vNDsvXsdrZ+3KKO 112 | bqijZuGNxH7tXGuLOO4XbTqphKv90ltumFaOKzdhuol93JHvN3c3IFTmwOiOwMIFqxUHTK8Fy8Zn 113 | VmvXyAsD/bmd4Kx0paXUWxAuDf//kPiog73+XajqKgZ0+1i7mqNn+CnvoQHCuqGGOs0+Dg9cTaBY 114 | XIPh5UBTBxUsbRXc7GPDW93h/NIyI1ontBpq7kwLljYVVeKNXsOC1gIRbA210Wmg5RsM3lBxL9rH 115 | rREbynahJYYzLjZo8VXACzV4btdyTPwLxiA0XDi+oGUTorii0nIEjzah4Jmbkppofgon5rqlaoe9 116 | B1ygWmlTrrU3ikphG7CWiHSfJalZ1/aAoSr6ZqhiwjI9ir4+htY0VITgnkLyUIWlkBxs18JwupQw 117 | obyU4AqN4ickPjqdF0nOnDfcRPARYbKj54On6PvRVPTTaAS9mYDa+qUUbNFfT3Hz+bjSDTUpsvxf 118 | yBBUUuTTD5nDJ3YZbDlcBHWwg3+SL+M0Gyf5PEmLbFokyStO8W35sSbNxyjL0nmWFOltkaav5P0v 119 | yD0ixvsEAAA= 120 | headers: 121 | Access-Control-Allow-Origin: 122 | - '*' 123 | Access-Control-Expose-Headers: 124 | - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, 125 | X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, 126 | X-GitHub-Media-Type 127 | Cache-Control: 128 | - private, max-age=60, s-maxage=60 129 | Content-Encoding: 130 | - gzip 131 | Content-Security-Policy: 132 | - default-src 'none' 133 | Content-Type: 134 | - application/json; charset=utf-8 135 | Date: 136 | - Tue, 10 Sep 2019 18:44:26 GMT 137 | ETag: 138 | - W/"566ed2d612496c35fdf0e7114d906425" 139 | Last-Modified: 140 | - Wed, 21 Aug 2019 20:15:11 GMT 141 | Referrer-Policy: 142 | - origin-when-cross-origin, strict-origin-when-cross-origin 143 | Server: 144 | - GitHub.com 145 | Status: 146 | - 200 OK 147 | Strict-Transport-Security: 148 | - max-age=31536000; includeSubdomains; preload 149 | Transfer-Encoding: 150 | - chunked 151 | Vary: 152 | - Accept, Authorization, Cookie, X-GitHub-OTP 153 | - Accept-Encoding 154 | X-Accepted-OAuth-Scopes: 155 | - '' 156 | X-Content-Type-Options: 157 | - nosniff 158 | X-Frame-Options: 159 | - deny 160 | X-GitHub-Media-Type: 161 | - github.v3; format=json 162 | X-GitHub-Request-Id: 163 | - F4D8:4203:3438D5:3E04C7:5D77EF0A 164 | X-OAuth-Scopes: 165 | - admin:org, admin:repo_hook, delete_repo, notifications, read:packages, repo, 166 | write:discussion, write:packages 167 | X-RateLimit-Limit: 168 | - '5000' 169 | X-RateLimit-Remaining: 170 | - '4983' 171 | X-RateLimit-Reset: 172 | - '1568144666' 173 | X-XSS-Protection: 174 | - 1; mode=block 175 | status: 176 | code: 200 177 | message: OK 178 | - request: 179 | body: '{"name": "fake-project", "private": false}' 180 | headers: 181 | Accept: 182 | - '*/*' 183 | Accept-Encoding: 184 | - gzip, deflate 185 | Connection: 186 | - keep-alive 187 | Content-Length: 188 | - '42' 189 | Content-Type: 190 | - application/json 191 | User-Agent: 192 | - PyGithub/Python 193 | authorization: 194 | - DUMMY 195 | method: POST 196 | uri: https://api.github.com/orgs/associatedpress/repos 197 | response: 198 | body: 199 | string: '{"id":207637081,"node_id":"MDEwOlJlcG9zaXRvcnkyMDc2MzcwODE=","name":"fake-project","full_name":"associatedpress/fake-project","private":false,"owner":{"login":"associatedpress","id":1165910,"node_id":"MDEyOk9yZ2FuaXphdGlvbjExNjU5MTA=","avatar_url":"https://avatars1.githubusercontent.com/u/1165910?v=4","gravatar_id":"","url":"https://api.github.com/users/associatedpress","html_url":"https://github.com/associatedpress","followers_url":"https://api.github.com/users/associatedpress/followers","following_url":"https://api.github.com/users/associatedpress/following{/other_user}","gists_url":"https://api.github.com/users/associatedpress/gists{/gist_id}","starred_url":"https://api.github.com/users/associatedpress/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/associatedpress/subscriptions","organizations_url":"https://api.github.com/users/associatedpress/orgs","repos_url":"https://api.github.com/users/associatedpress/repos","events_url":"https://api.github.com/users/associatedpress/events{/privacy}","received_events_url":"https://api.github.com/users/associatedpress/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/associatedpress/fake-project","description":null,"fork":false,"url":"https://api.github.com/repos/associatedpress/fake-project","forks_url":"https://api.github.com/repos/associatedpress/fake-project/forks","keys_url":"https://api.github.com/repos/associatedpress/fake-project/keys{/key_id}","collaborators_url":"https://api.github.com/repos/associatedpress/fake-project/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/associatedpress/fake-project/teams","hooks_url":"https://api.github.com/repos/associatedpress/fake-project/hooks","issue_events_url":"https://api.github.com/repos/associatedpress/fake-project/issues/events{/number}","events_url":"https://api.github.com/repos/associatedpress/fake-project/events","assignees_url":"https://api.github.com/repos/associatedpress/fake-project/assignees{/user}","branches_url":"https://api.github.com/repos/associatedpress/fake-project/branches{/branch}","tags_url":"https://api.github.com/repos/associatedpress/fake-project/tags","blobs_url":"https://api.github.com/repos/associatedpress/fake-project/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/associatedpress/fake-project/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/associatedpress/fake-project/git/refs{/sha}","trees_url":"https://api.github.com/repos/associatedpress/fake-project/git/trees{/sha}","statuses_url":"https://api.github.com/repos/associatedpress/fake-project/statuses/{sha}","languages_url":"https://api.github.com/repos/associatedpress/fake-project/languages","stargazers_url":"https://api.github.com/repos/associatedpress/fake-project/stargazers","contributors_url":"https://api.github.com/repos/associatedpress/fake-project/contributors","subscribers_url":"https://api.github.com/repos/associatedpress/fake-project/subscribers","subscription_url":"https://api.github.com/repos/associatedpress/fake-project/subscription","commits_url":"https://api.github.com/repos/associatedpress/fake-project/commits{/sha}","git_commits_url":"https://api.github.com/repos/associatedpress/fake-project/git/commits{/sha}","comments_url":"https://api.github.com/repos/associatedpress/fake-project/comments{/number}","issue_comment_url":"https://api.github.com/repos/associatedpress/fake-project/issues/comments{/number}","contents_url":"https://api.github.com/repos/associatedpress/fake-project/contents/{+path}","compare_url":"https://api.github.com/repos/associatedpress/fake-project/compare/{base}...{head}","merges_url":"https://api.github.com/repos/associatedpress/fake-project/merges","archive_url":"https://api.github.com/repos/associatedpress/fake-project/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/associatedpress/fake-project/downloads","issues_url":"https://api.github.com/repos/associatedpress/fake-project/issues{/number}","pulls_url":"https://api.github.com/repos/associatedpress/fake-project/pulls{/number}","milestones_url":"https://api.github.com/repos/associatedpress/fake-project/milestones{/number}","notifications_url":"https://api.github.com/repos/associatedpress/fake-project/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/associatedpress/fake-project/labels{/name}","releases_url":"https://api.github.com/repos/associatedpress/fake-project/releases{/id}","deployments_url":"https://api.github.com/repos/associatedpress/fake-project/deployments","created_at":"2019-09-10T18:44:26Z","updated_at":"2019-09-10T18:44:26Z","pushed_at":"2019-09-10T18:44:27Z","git_url":"git://github.com/associatedpress/fake-project.git","ssh_url":"git@github.com:associatedpress/fake-project.git","clone_url":"https://github.com/associatedpress/fake-project.git","svn_url":"https://github.com/associatedpress/fake-project","homepage":null,"size":0,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":0,"license":null,"forks":0,"open_issues":0,"watchers":0,"default_branch":"main","permissions":{"admin":true,"push":true,"pull":true},"allow_squash_merge":true,"allow_merge_commit":true,"allow_rebase_merge":true,"organization":{"login":"associatedpress","id":1165910,"node_id":"MDEyOk9yZ2FuaXphdGlvbjExNjU5MTA=","avatar_url":"https://avatars1.githubusercontent.com/u/1165910?v=4","gravatar_id":"","url":"https://api.github.com/users/associatedpress","html_url":"https://github.com/associatedpress","followers_url":"https://api.github.com/users/associatedpress/followers","following_url":"https://api.github.com/users/associatedpress/following{/other_user}","gists_url":"https://api.github.com/users/associatedpress/gists{/gist_id}","starred_url":"https://api.github.com/users/associatedpress/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/associatedpress/subscriptions","organizations_url":"https://api.github.com/users/associatedpress/orgs","repos_url":"https://api.github.com/users/associatedpress/repos","events_url":"https://api.github.com/users/associatedpress/events{/privacy}","received_events_url":"https://api.github.com/users/associatedpress/received_events","type":"Organization","site_admin":false},"network_count":0,"subscribers_count":12}' 200 | headers: 201 | Access-Control-Allow-Origin: 202 | - '*' 203 | Access-Control-Expose-Headers: 204 | - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, 205 | X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, 206 | X-GitHub-Media-Type 207 | Cache-Control: 208 | - private, max-age=60, s-maxage=60 209 | Content-Length: 210 | - '6477' 211 | Content-Security-Policy: 212 | - default-src 'none' 213 | Content-Type: 214 | - application/json; charset=utf-8 215 | Date: 216 | - Tue, 10 Sep 2019 18:44:27 GMT 217 | ETag: 218 | - '"94acebfb2e92e7e2b56b95386b284f69"' 219 | Location: 220 | - https://api.github.com/repos/associatedpress/fake-project 221 | Referrer-Policy: 222 | - origin-when-cross-origin, strict-origin-when-cross-origin 223 | Server: 224 | - GitHub.com 225 | Status: 226 | - 201 Created 227 | Strict-Transport-Security: 228 | - max-age=31536000; includeSubdomains; preload 229 | Vary: 230 | - Accept, Authorization, Cookie, X-GitHub-OTP 231 | - Accept-Encoding 232 | X-Accepted-OAuth-Scopes: 233 | - public_repo, repo 234 | X-Content-Type-Options: 235 | - nosniff 236 | X-Frame-Options: 237 | - deny 238 | X-GitHub-Media-Type: 239 | - github.v3; format=json 240 | X-GitHub-Request-Id: 241 | - F4D8:4203:3438DB:3E04CD:5D77EF0A 242 | X-OAuth-Scopes: 243 | - admin:org, admin:repo_hook, delete_repo, notifications, read:packages, repo, 244 | write:discussion, write:packages 245 | X-RateLimit-Limit: 246 | - '5000' 247 | X-RateLimit-Remaining: 248 | - '4982' 249 | X-RateLimit-Reset: 250 | - '1568144666' 251 | X-XSS-Protection: 252 | - 1; mode=block 253 | status: 254 | code: 201 255 | message: Created 256 | version: 1 257 | -------------------------------------------------------------------------------- /tests/commands/cassettes/test_repo_already_exists.yaml: -------------------------------------------------------------------------------- 1 | interactions: 2 | - request: 3 | body: null 4 | headers: 5 | Accept: 6 | - '*/*' 7 | Accept-Encoding: 8 | - gzip, deflate 9 | Connection: 10 | - keep-alive 11 | User-Agent: 12 | - PyGithub/Python 13 | authorization: 14 | - DUMMY 15 | method: GET 16 | uri: https://api.github.com/user/orgs 17 | response: 18 | body: 19 | string: !!binary | 20 | H4sIAAAAAAAAA62X7WrbMBSGb0X479Imjuu1KZQxSDc6cLuyho2NURRbcZQolpHkdEkp7DZ2e7uS 21 | HTkfs1yHWMb/GuPnVaif8/rkx7PDeEwT59KJeJgtSKJCxrPI6Tg0ci4HnnfhdZyER+RRf3aC4fXq 22 | bj5Yfe9/yPC3dBp9ZMvxbL4O1vEamEwwuGmqVCovu12c0tOYqmk2Pg35ostFLLvlUwRJuXy05Lo5 23 | BeeRJXxhe3yDAT/lfG6P55T+D0mZEXt8gwG/IIsxEfYBW+65u/njBaLSbMxo+Ng00cSLwXiJFRbl 24 | B5RflP3t080kESFPFDyL/EFn3dybd8urM/hqEZGhoKmiXFvmvHT+K/d5paY8+cQzkeSPUyvme97Z 25 | ef+4cyNw7t4L4qsrAI/7Uz6qrncGZ++diVt7Z+LW3pl4A+/MgDa8MxPb9m4jT5V4ScZYUT2+JGJJ 26 | ydPWugv/zPPd49bF7u0wcIP7mtYVTqkr3A6xd21PWmu2J60N25MN5NqzbXi1D2umVO9glW3MqFLK 27 | eZgSxFOSIAkNFhK0e7ehBU1oEqOUYTXhYmF0HpaShxQrEqWCyF3rue5bf+D2jgt4/et2NvKDh/f1 28 | au/1aXU9LJH2OpYDrK0sB1jLWQ5o4Gg5og1Vy5nNjHUPGrt1qVJZQ0XtLmEk1K/mvYiDnj8Y1BHR 29 | D4Yj/66uiOWz6mpocPYSmri1giZuLaCJN9DPDGhDPjOxmXqH9z53Y0+lerotY44Z4hN0B+Zd78xD 30 | VCLFUSgItCJScNuECqnQRBDSQbBQQlFOSSLpEj5KhZMIi4iuSdRBjCZzEiFJlE7duYygWDOmJIpg 31 | TUXQwHnoKKFQuuiLglPkqTEIOhRui2Z6E8WMysV2Lej3ev3euXd+vJdvnoLhzdPtOvBqraOVJ9ad 32 | idew/WBUZFhPR0WG9YhUZDSYk4qUNoalIrbZxBwu651hlSPzlfz9/UcQlMIrAzpajwce80zBFHCx 33 | UoSB/zF6k3tuCK0vzKk6CRndmex7A/+tV6PYb9xgPXdvZ4HejY//sDKPqqtwgbJ3twhbS1uErW0t 34 | wg00LeJt+FnMa13MrTCVYg43fqEThGHLzeIYjxnRVb2Adj4BK6HHOWe61uEKjmE31lWcCj6DdUO3 35 | 789/tzazUXoSAAA= 36 | headers: 37 | Access-Control-Allow-Origin: 38 | - '*' 39 | Access-Control-Expose-Headers: 40 | - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, 41 | X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, 42 | X-GitHub-Media-Type 43 | Cache-Control: 44 | - private, max-age=60, s-maxage=60 45 | Content-Encoding: 46 | - gzip 47 | Content-Security-Policy: 48 | - default-src 'none' 49 | Content-Type: 50 | - application/json; charset=utf-8 51 | Date: 52 | - Tue, 10 Sep 2019 17:19:36 GMT 53 | ETag: 54 | - W/"f6153453e8455ef3f55031d134f82d15" 55 | Referrer-Policy: 56 | - origin-when-cross-origin, strict-origin-when-cross-origin 57 | Server: 58 | - GitHub.com 59 | Status: 60 | - 200 OK 61 | Strict-Transport-Security: 62 | - max-age=31536000; includeSubdomains; preload 63 | Transfer-Encoding: 64 | - chunked 65 | Vary: 66 | - Accept, Authorization, Cookie, X-GitHub-OTP 67 | - Accept-Encoding 68 | X-Accepted-OAuth-Scopes: 69 | - admin:org, read:org, repo, user, write:org 70 | X-Content-Type-Options: 71 | - nosniff 72 | X-Frame-Options: 73 | - deny 74 | X-GitHub-Media-Type: 75 | - github.v3; format=json 76 | X-GitHub-Request-Id: 77 | - F230:5348:70330B:845D67:5D77DB27 78 | X-OAuth-Scopes: 79 | - admin:org, admin:repo_hook, delete_repo, notifications, read:packages, repo, 80 | write:discussion, write:packages 81 | X-RateLimit-Limit: 82 | - '5000' 83 | X-RateLimit-Remaining: 84 | - '4999' 85 | X-RateLimit-Reset: 86 | - '1568139575' 87 | X-XSS-Protection: 88 | - 1; mode=block 89 | status: 90 | code: 200 91 | message: OK 92 | - request: 93 | body: null 94 | headers: 95 | Accept: 96 | - '*/*' 97 | Accept-Encoding: 98 | - gzip, deflate 99 | Connection: 100 | - keep-alive 101 | User-Agent: 102 | - PyGithub/Python 103 | authorization: 104 | - DUMMY 105 | method: GET 106 | uri: https://api.github.com/user 107 | response: 108 | body: 109 | string: !!binary | 110 | H4sIAAAAAAAAA52UXW/aMBiF/0rkayAfa9kSqWqrVbuYxLSpdJp6g4xjEiPHjvwBoqj/fccJg8LF 111 | pHCVxH7P48Pr97AnUldCkYK8WeebShuuyIiIkhSf8ixJRkTpki/CN5k9/Zr+/vNDsvXsdrZ+3KKO 112 | bqijZuGNxH7tXGuLOO4XbTqphKv90ltumFaOKzdhuol93JHvN3c3IFTmwOiOwMIFqxUHTK8Fy8Zn 113 | VmvXyAsD/bmd4Kx0paXUWxAuDf//kPiog73+XajqKgZ0+1i7mqNn+CnvoQHCuqGGOs0+Dg9cTaBY 114 | XIPh5UBTBxUsbRXc7GPDW93h/NIyI1ontBpq7kwLljYVVeKNXsOC1gIRbA210Wmg5RsM3lBxL9rH 115 | rREbynahJYYzLjZo8VXACzV4btdyTPwLxiA0XDi+oGUTorii0nIEjzah4Jmbkppofgon5rqlaoe9 116 | B1ygWmlTrrU3ikphG7CWiHSfJalZ1/aAoSr6ZqhiwjI9ir4+htY0VITgnkLyUIWlkBxs18JwupQw 117 | obyU4AqN4ickPjqdF0nOnDfcRPARYbKj54On6PvRVPTTaAS9mYDa+qUUbNFfT3Hz+bjSDTUpsvxf 118 | yBBUUuTTD5nDJ3YZbDlcBHWwg3+SL+M0Gyf5PEmLbFokyStO8W35sSbNxyjL0nmWFOltkaav5P0v 119 | yD0ixvsEAAA= 120 | headers: 121 | Access-Control-Allow-Origin: 122 | - '*' 123 | Access-Control-Expose-Headers: 124 | - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, 125 | X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, 126 | X-GitHub-Media-Type 127 | Cache-Control: 128 | - private, max-age=60, s-maxage=60 129 | Content-Encoding: 130 | - gzip 131 | Content-Security-Policy: 132 | - default-src 'none' 133 | Content-Type: 134 | - application/json; charset=utf-8 135 | Date: 136 | - Tue, 10 Sep 2019 17:19:36 GMT 137 | ETag: 138 | - W/"566ed2d612496c35fdf0e7114d906425" 139 | Last-Modified: 140 | - Wed, 21 Aug 2019 20:15:11 GMT 141 | Referrer-Policy: 142 | - origin-when-cross-origin, strict-origin-when-cross-origin 143 | Server: 144 | - GitHub.com 145 | Status: 146 | - 200 OK 147 | Strict-Transport-Security: 148 | - max-age=31536000; includeSubdomains; preload 149 | Transfer-Encoding: 150 | - chunked 151 | Vary: 152 | - Accept, Authorization, Cookie, X-GitHub-OTP 153 | - Accept-Encoding 154 | X-Accepted-OAuth-Scopes: 155 | - '' 156 | X-Content-Type-Options: 157 | - nosniff 158 | X-Frame-Options: 159 | - deny 160 | X-GitHub-Media-Type: 161 | - github.v3; format=json 162 | X-GitHub-Request-Id: 163 | - F230:5348:703316:845D79:5D77DB28 164 | X-OAuth-Scopes: 165 | - admin:org, admin:repo_hook, delete_repo, notifications, read:packages, repo, 166 | write:discussion, write:packages 167 | X-RateLimit-Limit: 168 | - '5000' 169 | X-RateLimit-Remaining: 170 | - '4998' 171 | X-RateLimit-Reset: 172 | - '1568139575' 173 | X-XSS-Protection: 174 | - 1; mode=block 175 | status: 176 | code: 200 177 | message: OK 178 | - request: 179 | body: null 180 | headers: 181 | Accept: 182 | - '*/*' 183 | Accept-Encoding: 184 | - gzip, deflate 185 | Connection: 186 | - keep-alive 187 | User-Agent: 188 | - PyGithub/Python 189 | authorization: 190 | - DUMMY 191 | method: GET 192 | uri: https://api.github.com/search/repositories?q=fake-project%2Buser%3Azstumgoren 193 | response: 194 | body: 195 | string: !!binary | 196 | H4sIAAAAAAAAA6tWKskvScyJT84vzStRsjLQUcrMS87PLchJLUmNL0otLs0pKVaySkvMKU4FSpWk 197 | 5gJ50bG1AMhF9bc3AAAA 198 | headers: 199 | Access-Control-Allow-Origin: 200 | - '*' 201 | Access-Control-Expose-Headers: 202 | - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, 203 | X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, 204 | X-GitHub-Media-Type 205 | Cache-Control: 206 | - no-cache 207 | Content-Encoding: 208 | - gzip 209 | Content-Security-Policy: 210 | - default-src 'none' 211 | Content-Type: 212 | - application/json; charset=utf-8 213 | Date: 214 | - Tue, 10 Sep 2019 17:19:36 GMT 215 | Referrer-Policy: 216 | - origin-when-cross-origin, strict-origin-when-cross-origin 217 | Server: 218 | - GitHub.com 219 | Status: 220 | - 200 OK 221 | Strict-Transport-Security: 222 | - max-age=31536000; includeSubdomains; preload 223 | Transfer-Encoding: 224 | - chunked 225 | Vary: 226 | - Accept-Encoding 227 | X-Accepted-OAuth-Scopes: 228 | - '' 229 | X-Content-Type-Options: 230 | - nosniff 231 | X-Frame-Options: 232 | - deny 233 | X-GitHub-Media-Type: 234 | - github.v3; format=json 235 | X-GitHub-Request-Id: 236 | - F231:7CF6:69B223:7DE605:5D77DB28 237 | X-OAuth-Scopes: 238 | - admin:org, admin:repo_hook, delete_repo, notifications, read:packages, repo, 239 | write:discussion, write:packages 240 | X-RateLimit-Limit: 241 | - '30' 242 | X-RateLimit-Remaining: 243 | - '29' 244 | X-RateLimit-Reset: 245 | - '1568136036' 246 | X-XSS-Protection: 247 | - 1; mode=block 248 | status: 249 | code: 200 250 | message: OK 251 | - request: 252 | body: '{"name": "fake-project", "private": true}' 253 | headers: 254 | Accept: 255 | - '*/*' 256 | Accept-Encoding: 257 | - gzip, deflate 258 | Connection: 259 | - keep-alive 260 | Content-Length: 261 | - '41' 262 | Content-Type: 263 | - application/json 264 | User-Agent: 265 | - PyGithub/Python 266 | authorization: 267 | - DUMMY 268 | method: POST 269 | uri: https://api.github.com/user/repos 270 | response: 271 | body: 272 | string: '{"message":"Repository creation failed.","errors":[{"resource":"Repository","code":"custom","field":"name","message":"name 273 | already exists on this account"}],"documentation_url":"https://developer.github.com/v3/repos/#create"}' 274 | headers: 275 | Access-Control-Allow-Origin: 276 | - '*' 277 | Access-Control-Expose-Headers: 278 | - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, 279 | X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, 280 | X-GitHub-Media-Type 281 | Content-Length: 282 | - '225' 283 | Content-Security-Policy: 284 | - default-src 'none' 285 | Content-Type: 286 | - application/json; charset=utf-8 287 | Date: 288 | - Tue, 10 Sep 2019 17:19:36 GMT 289 | Referrer-Policy: 290 | - origin-when-cross-origin, strict-origin-when-cross-origin 291 | Server: 292 | - GitHub.com 293 | Status: 294 | - 422 Unprocessable Entity 295 | Strict-Transport-Security: 296 | - max-age=31536000; includeSubdomains; preload 297 | X-Accepted-OAuth-Scopes: 298 | - public_repo, repo 299 | X-Content-Type-Options: 300 | - nosniff 301 | X-Frame-Options: 302 | - deny 303 | X-GitHub-Media-Type: 304 | - github.v3; format=json 305 | X-GitHub-Request-Id: 306 | - F230:5348:70333E:845D85:5D77DB28 307 | X-OAuth-Scopes: 308 | - admin:org, admin:repo_hook, delete_repo, notifications, read:packages, repo, 309 | write:discussion, write:packages 310 | X-RateLimit-Limit: 311 | - '5000' 312 | X-RateLimit-Remaining: 313 | - '4997' 314 | X-RateLimit-Reset: 315 | - '1568139575' 316 | X-XSS-Protection: 317 | - 1; mode=block 318 | status: 319 | code: 422 320 | message: Unprocessable Entity 321 | version: 1 322 | -------------------------------------------------------------------------------- /tests/commands/cassettes/test_repo_already_exists_org_account.yaml: -------------------------------------------------------------------------------- 1 | interactions: 2 | - request: 3 | body: null 4 | headers: 5 | Accept: 6 | - '*/*' 7 | Accept-Encoding: 8 | - gzip, deflate 9 | Connection: 10 | - keep-alive 11 | User-Agent: 12 | - PyGithub/Python 13 | authorization: 14 | - DUMMY 15 | method: GET 16 | uri: https://api.github.com/user/orgs 17 | response: 18 | body: 19 | string: !!binary | 20 | H4sIAAAAAAAAA62X7WrbMBSGb0X479Imjuu1KZQxSDc6cLuyho2NURRbcZQolpHkdEkp7DZ2e7uS 21 | HTkfs1yHWMb/GuPnVaif8/rkx7PDeEwT59KJeJgtSKJCxrPI6Tg0ci4HnnfhdZyER+RRf3aC4fXq 22 | bj5Yfe9/yPC3dBp9ZMvxbL4O1vEamEwwuGmqVCovu12c0tOYqmk2Pg35ostFLLvlUwRJuXy05Lo5 23 | BeeRJXxhe3yDAT/lfG6P55T+D0mZEXt8gwG/IIsxEfYBW+65u/njBaLSbMxo+Ng00cSLwXiJFRbl 24 | B5RflP3t080kESFPFDyL/EFn3dybd8urM/hqEZGhoKmiXFvmvHT+K/d5paY8+cQzkeSPUyvme97Z 25 | ef+4cyNw7t4L4qsrAI/7Uz6qrncGZ++diVt7Z+LW3pl4A+/MgDa8MxPb9m4jT5V4ScZYUT2+JGJJ 26 | ydPWugv/zPPd49bF7u0wcIP7mtYVTqkr3A6xd21PWmu2J60N25MN5NqzbXi1D2umVO9glW3MqFLK 27 | eZgSxFOSIAkNFhK0e7ehBU1oEqOUYTXhYmF0HpaShxQrEqWCyF3rue5bf+D2jgt4/et2NvKDh/f1 28 | au/1aXU9LJH2OpYDrK0sB1jLWQ5o4Gg5og1Vy5nNjHUPGrt1qVJZQ0XtLmEk1K/mvYiDnj8Y1BHR 29 | D4Yj/66uiOWz6mpocPYSmri1giZuLaCJN9DPDGhDPjOxmXqH9z53Y0+lerotY44Z4hN0B+Zd78xD 30 | VCLFUSgItCJScNuECqnQRBDSQbBQQlFOSSLpEj5KhZMIi4iuSdRBjCZzEiFJlE7duYygWDOmJIpg 31 | TUXQwHnoKKFQuuiLglPkqTEIOhRui2Z6E8WMysV2Lej3ev3euXd+vJdvnoLhzdPtOvBqraOVJ9ad 32 | idew/WBUZFhPR0WG9YhUZDSYk4qUNoalIrbZxBwu651hlSPzlfz9/UcQlMIrAzpajwce80zBFHCx 33 | UoSB/zF6k3tuCK0vzKk6CRndmex7A/+tV6PYb9xgPXdvZ4HejY//sDKPqqtwgbJ3twhbS1uErW0t 34 | wg00LeJt+FnMa13MrTCVYg43fqEThGHLzeIYjxnRVb2Adj4BK6HHOWe61uEKjmE31lWcCj6DdUO3 35 | 789/tzazUXoSAAA= 36 | headers: 37 | Access-Control-Allow-Origin: 38 | - '*' 39 | Access-Control-Expose-Headers: 40 | - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, 41 | X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, 42 | X-GitHub-Media-Type 43 | Cache-Control: 44 | - private, max-age=60, s-maxage=60 45 | Content-Encoding: 46 | - gzip 47 | Content-Security-Policy: 48 | - default-src 'none' 49 | Content-Type: 50 | - application/json; charset=utf-8 51 | Date: 52 | - Tue, 10 Sep 2019 18:46:39 GMT 53 | ETag: 54 | - W/"f6153453e8455ef3f55031d134f82d15" 55 | Referrer-Policy: 56 | - origin-when-cross-origin, strict-origin-when-cross-origin 57 | Server: 58 | - GitHub.com 59 | Status: 60 | - 200 OK 61 | Strict-Transport-Security: 62 | - max-age=31536000; includeSubdomains; preload 63 | Transfer-Encoding: 64 | - chunked 65 | Vary: 66 | - Accept, Authorization, Cookie, X-GitHub-OTP 67 | - Accept-Encoding 68 | X-Accepted-OAuth-Scopes: 69 | - admin:org, read:org, repo, user, write:org 70 | X-Content-Type-Options: 71 | - nosniff 72 | X-Frame-Options: 73 | - deny 74 | X-GitHub-Media-Type: 75 | - github.v3; format=json 76 | X-GitHub-Request-Id: 77 | - F502:676D:7D1666:92C526:5D77EF8F 78 | X-OAuth-Scopes: 79 | - admin:org, admin:repo_hook, delete_repo, notifications, read:packages, repo, 80 | write:discussion, write:packages 81 | X-RateLimit-Limit: 82 | - '5000' 83 | X-RateLimit-Remaining: 84 | - '4978' 85 | X-RateLimit-Reset: 86 | - '1568144666' 87 | X-XSS-Protection: 88 | - 1; mode=block 89 | status: 90 | code: 200 91 | message: OK 92 | - request: 93 | body: null 94 | headers: 95 | Accept: 96 | - '*/*' 97 | Accept-Encoding: 98 | - gzip, deflate 99 | Connection: 100 | - keep-alive 101 | User-Agent: 102 | - PyGithub/Python 103 | authorization: 104 | - DUMMY 105 | method: GET 106 | uri: https://api.github.com/user 107 | response: 108 | body: 109 | string: !!binary | 110 | H4sIAAAAAAAAA52UXW/aMBiF/0rkayAfa9kSqWqrVbuYxLSpdJp6g4xjEiPHjvwBoqj/fccJg8LF 111 | pHCVxH7P48Pr97AnUldCkYK8WeebShuuyIiIkhSf8ixJRkTpki/CN5k9/Zr+/vNDsvXsdrZ+3KKO 112 | bqijZuGNxH7tXGuLOO4XbTqphKv90ltumFaOKzdhuol93JHvN3c3IFTmwOiOwMIFqxUHTK8Fy8Zn 113 | VmvXyAsD/bmd4Kx0paXUWxAuDf//kPiog73+XajqKgZ0+1i7mqNn+CnvoQHCuqGGOs0+Dg9cTaBY 114 | XIPh5UBTBxUsbRXc7GPDW93h/NIyI1ontBpq7kwLljYVVeKNXsOC1gIRbA210Wmg5RsM3lBxL9rH 115 | rREbynahJYYzLjZo8VXACzV4btdyTPwLxiA0XDi+oGUTorii0nIEjzah4Jmbkppofgon5rqlaoe9 116 | B1ygWmlTrrU3ikphG7CWiHSfJalZ1/aAoSr6ZqhiwjI9ir4+htY0VITgnkLyUIWlkBxs18JwupQw 117 | obyU4AqN4ickPjqdF0nOnDfcRPARYbKj54On6PvRVPTTaAS9mYDa+qUUbNFfT3Hz+bjSDTUpsvxf 118 | yBBUUuTTD5nDJ3YZbDlcBHWwg3+SL+M0Gyf5PEmLbFokyStO8W35sSbNxyjL0nmWFOltkaav5P0v 119 | yD0ixvsEAAA= 120 | headers: 121 | Access-Control-Allow-Origin: 122 | - '*' 123 | Access-Control-Expose-Headers: 124 | - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, 125 | X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, 126 | X-GitHub-Media-Type 127 | Cache-Control: 128 | - private, max-age=60, s-maxage=60 129 | Content-Encoding: 130 | - gzip 131 | Content-Security-Policy: 132 | - default-src 'none' 133 | Content-Type: 134 | - application/json; charset=utf-8 135 | Date: 136 | - Tue, 10 Sep 2019 18:46:39 GMT 137 | ETag: 138 | - W/"566ed2d612496c35fdf0e7114d906425" 139 | Last-Modified: 140 | - Wed, 21 Aug 2019 20:15:11 GMT 141 | Referrer-Policy: 142 | - origin-when-cross-origin, strict-origin-when-cross-origin 143 | Server: 144 | - GitHub.com 145 | Status: 146 | - 200 OK 147 | Strict-Transport-Security: 148 | - max-age=31536000; includeSubdomains; preload 149 | Transfer-Encoding: 150 | - chunked 151 | Vary: 152 | - Accept, Authorization, Cookie, X-GitHub-OTP 153 | - Accept-Encoding 154 | X-Accepted-OAuth-Scopes: 155 | - '' 156 | X-Content-Type-Options: 157 | - nosniff 158 | X-Frame-Options: 159 | - deny 160 | X-GitHub-Media-Type: 161 | - github.v3; format=json 162 | X-GitHub-Request-Id: 163 | - F502:676D:7D1677:92C539:5D77EF8F 164 | X-OAuth-Scopes: 165 | - admin:org, admin:repo_hook, delete_repo, notifications, read:packages, repo, 166 | write:discussion, write:packages 167 | X-RateLimit-Limit: 168 | - '5000' 169 | X-RateLimit-Remaining: 170 | - '4977' 171 | X-RateLimit-Reset: 172 | - '1568144666' 173 | X-XSS-Protection: 174 | - 1; mode=block 175 | status: 176 | code: 200 177 | message: OK 178 | - request: 179 | body: '{"name": "fake-project", "private": false}' 180 | headers: 181 | Accept: 182 | - '*/*' 183 | Accept-Encoding: 184 | - gzip, deflate 185 | Connection: 186 | - keep-alive 187 | Content-Length: 188 | - '42' 189 | Content-Type: 190 | - application/json 191 | User-Agent: 192 | - PyGithub/Python 193 | authorization: 194 | - DUMMY 195 | method: POST 196 | uri: https://api.github.com/orgs/associatedpress/repos 197 | response: 198 | body: 199 | string: '{"message":"Repository creation failed.","errors":[{"resource":"Repository","code":"custom","field":"name","message":"name 200 | already exists on this account"}],"documentation_url":"https://developer.github.com/v3/repos/#create"}' 201 | headers: 202 | Access-Control-Allow-Origin: 203 | - '*' 204 | Access-Control-Expose-Headers: 205 | - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, 206 | X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, 207 | X-GitHub-Media-Type 208 | Content-Length: 209 | - '225' 210 | Content-Security-Policy: 211 | - default-src 'none' 212 | Content-Type: 213 | - application/json; charset=utf-8 214 | Date: 215 | - Tue, 10 Sep 2019 18:46:40 GMT 216 | Referrer-Policy: 217 | - origin-when-cross-origin, strict-origin-when-cross-origin 218 | Server: 219 | - GitHub.com 220 | Status: 221 | - 422 Unprocessable Entity 222 | Strict-Transport-Security: 223 | - max-age=31536000; includeSubdomains; preload 224 | X-Accepted-OAuth-Scopes: 225 | - public_repo, repo 226 | X-Content-Type-Options: 227 | - nosniff 228 | X-Frame-Options: 229 | - deny 230 | X-GitHub-Media-Type: 231 | - github.v3; format=json 232 | X-GitHub-Request-Id: 233 | - F502:676D:7D1689:92C557:5D77EF8F 234 | X-OAuth-Scopes: 235 | - admin:org, admin:repo_hook, delete_repo, notifications, read:packages, repo, 236 | write:discussion, write:packages 237 | X-RateLimit-Limit: 238 | - '5000' 239 | X-RateLimit-Remaining: 240 | - '4976' 241 | X-RateLimit-Reset: 242 | - '1568144666' 243 | X-XSS-Protection: 244 | - 1; mode=block 245 | status: 246 | code: 422 247 | message: Unprocessable Entity 248 | version: 1 249 | -------------------------------------------------------------------------------- /tests/commands/cassettes/test_repo_already_initialized.yaml: -------------------------------------------------------------------------------- 1 | interactions: 2 | - request: 3 | body: null 4 | headers: 5 | Accept: 6 | - '*/*' 7 | Accept-Encoding: 8 | - gzip, deflate 9 | Connection: 10 | - keep-alive 11 | User-Agent: 12 | - PyGithub/Python 13 | authorization: 14 | - DUMMY 15 | method: GET 16 | uri: https://api.github.com/user/orgs 17 | response: 18 | body: 19 | string: !!binary | 20 | H4sIAAAAAAAAA62X7WrbMBSGb0X479Imjuu1KZQxSDc6cLuyho2NURRbcZQolpHkdEkp7DZ2e7uS 21 | HTkfs1yHWMb/GuPnVaif8/rkx7PDeEwT59KJeJgtSKJCxrPI6Tg0ci4HnnfhdZyER+RRf3aC4fXq 22 | bj5Yfe9/yPC3dBp9ZMvxbL4O1vEamEwwuGmqVCovu12c0tOYqmk2Pg35ostFLLvlUwRJuXy05Lo5 23 | BeeRJXxhe3yDAT/lfG6P55T+D0mZEXt8gwG/IIsxEfYBW+65u/njBaLSbMxo+Ng00cSLwXiJFRbl 24 | B5RflP3t080kESFPFDyL/EFn3dybd8urM/hqEZGhoKmiXFvmvHT+K/d5paY8+cQzkeSPUyvme97Z 25 | ef+4cyNw7t4L4qsrAI/7Uz6qrncGZ++diVt7Z+LW3pl4A+/MgDa8MxPb9m4jT5V4ScZYUT2+JGJJ 26 | ydPWugv/zPPd49bF7u0wcIP7mtYVTqkr3A6xd21PWmu2J60N25MN5NqzbXi1D2umVO9glW3MqFLK 27 | eZgSxFOSIAkNFhK0e7ehBU1oEqOUYTXhYmF0HpaShxQrEqWCyF3rue5bf+D2jgt4/et2NvKDh/f1 28 | au/1aXU9LJH2OpYDrK0sB1jLWQ5o4Gg5og1Vy5nNjHUPGrt1qVJZQ0XtLmEk1K/mvYiDnj8Y1BHR 29 | D4Yj/66uiOWz6mpocPYSmri1giZuLaCJN9DPDGhDPjOxmXqH9z53Y0+lerotY44Z4hN0B+Zd78xD 30 | VCLFUSgItCJScNuECqnQRBDSQbBQQlFOSSLpEj5KhZMIi4iuSdRBjCZzEiFJlE7duYygWDOmJIpg 31 | TUXQwHnoKKFQuuiLglPkqTEIOhRui2Z6E8WMysV2Lej3ev3euXd+vJdvnoLhzdPtOvBqraOVJ9ad 32 | idew/WBUZFhPR0WG9YhUZDSYk4qUNoalIrbZxBwu651hlSPzlfz9/UcQlMIrAzpajwce80zBFHCx 33 | UoSB/zF6k3tuCK0vzKk6CRndmex7A/+tV6PYb9xgPXdvZ4HejY//sDKPqqtwgbJ3twhbS1uErW0t 34 | wg00LeJt+FnMa13MrTCVYg43fqEThGHLzeIYjxnRVb2Adj4BK6HHOWe61uEKjmE31lWcCj6DdUO3 35 | 789/tzazUXoSAAA= 36 | headers: 37 | Access-Control-Allow-Origin: 38 | - '*' 39 | Access-Control-Expose-Headers: 40 | - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, 41 | X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, 42 | X-GitHub-Media-Type 43 | Cache-Control: 44 | - private, max-age=60, s-maxage=60 45 | Content-Encoding: 46 | - gzip 47 | Content-Security-Policy: 48 | - default-src 'none' 49 | Content-Type: 50 | - application/json; charset=utf-8 51 | Date: 52 | - Tue, 10 Sep 2019 17:54:12 GMT 53 | ETag: 54 | - W/"f6153453e8455ef3f55031d134f82d15" 55 | Referrer-Policy: 56 | - origin-when-cross-origin, strict-origin-when-cross-origin 57 | Server: 58 | - GitHub.com 59 | Status: 60 | - 200 OK 61 | Strict-Transport-Security: 62 | - max-age=31536000; includeSubdomains; preload 63 | Transfer-Encoding: 64 | - chunked 65 | Vary: 66 | - Accept, Authorization, Cookie, X-GitHub-OTP 67 | - Accept-Encoding 68 | X-Accepted-OAuth-Scopes: 69 | - admin:org, read:org, repo, user, write:org 70 | X-Content-Type-Options: 71 | - nosniff 72 | X-Frame-Options: 73 | - deny 74 | X-GitHub-Media-Type: 75 | - github.v3; format=json 76 | X-GitHub-Request-Id: 77 | - F35A:533C:61F74:76324:5D77E342 78 | X-OAuth-Scopes: 79 | - admin:org, admin:repo_hook, delete_repo, notifications, read:packages, repo, 80 | write:discussion, write:packages 81 | X-RateLimit-Limit: 82 | - '5000' 83 | X-RateLimit-Remaining: 84 | - '4999' 85 | X-RateLimit-Reset: 86 | - '1568141652' 87 | X-XSS-Protection: 88 | - 1; mode=block 89 | status: 90 | code: 200 91 | message: OK 92 | - request: 93 | body: null 94 | headers: 95 | Accept: 96 | - '*/*' 97 | Accept-Encoding: 98 | - gzip, deflate 99 | Connection: 100 | - keep-alive 101 | User-Agent: 102 | - PyGithub/Python 103 | authorization: 104 | - DUMMY 105 | method: GET 106 | uri: https://api.github.com/user 107 | response: 108 | body: 109 | string: !!binary | 110 | H4sIAAAAAAAAA52UXW/aMBiF/0rkayAfa9kSqWqrVbuYxLSpdJp6g4xjEiPHjvwBoqj/fccJg8LF 111 | pHCVxH7P48Pr97AnUldCkYK8WeebShuuyIiIkhSf8ixJRkTpki/CN5k9/Zr+/vNDsvXsdrZ+3KKO 112 | bqijZuGNxH7tXGuLOO4XbTqphKv90ltumFaOKzdhuol93JHvN3c3IFTmwOiOwMIFqxUHTK8Fy8Zn 113 | VmvXyAsD/bmd4Kx0paXUWxAuDf//kPiog73+XajqKgZ0+1i7mqNn+CnvoQHCuqGGOs0+Dg9cTaBY 114 | XIPh5UBTBxUsbRXc7GPDW93h/NIyI1ontBpq7kwLljYVVeKNXsOC1gIRbA210Wmg5RsM3lBxL9rH 115 | rREbynahJYYzLjZo8VXACzV4btdyTPwLxiA0XDi+oGUTorii0nIEjzah4Jmbkppofgon5rqlaoe9 116 | B1ygWmlTrrU3ikphG7CWiHSfJalZ1/aAoSr6ZqhiwjI9ir4+htY0VITgnkLyUIWlkBxs18JwupQw 117 | obyU4AqN4ickPjqdF0nOnDfcRPARYbKj54On6PvRVPTTaAS9mYDa+qUUbNFfT3Hz+bjSDTUpsvxf 118 | yBBUUuTTD5nDJ3YZbDlcBHWwg3+SL+M0Gyf5PEmLbFokyStO8W35sSbNxyjL0nmWFOltkaav5P0v 119 | yD0ixvsEAAA= 120 | headers: 121 | Access-Control-Allow-Origin: 122 | - '*' 123 | Access-Control-Expose-Headers: 124 | - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, 125 | X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, 126 | X-GitHub-Media-Type 127 | Cache-Control: 128 | - private, max-age=60, s-maxage=60 129 | Content-Encoding: 130 | - gzip 131 | Content-Security-Policy: 132 | - default-src 'none' 133 | Content-Type: 134 | - application/json; charset=utf-8 135 | Date: 136 | - Tue, 10 Sep 2019 17:54:12 GMT 137 | ETag: 138 | - W/"566ed2d612496c35fdf0e7114d906425" 139 | Last-Modified: 140 | - Wed, 21 Aug 2019 20:15:11 GMT 141 | Referrer-Policy: 142 | - origin-when-cross-origin, strict-origin-when-cross-origin 143 | Server: 144 | - GitHub.com 145 | Status: 146 | - 200 OK 147 | Strict-Transport-Security: 148 | - max-age=31536000; includeSubdomains; preload 149 | Transfer-Encoding: 150 | - chunked 151 | Vary: 152 | - Accept, Authorization, Cookie, X-GitHub-OTP 153 | - Accept-Encoding 154 | X-Accepted-OAuth-Scopes: 155 | - '' 156 | X-Content-Type-Options: 157 | - nosniff 158 | X-Frame-Options: 159 | - deny 160 | X-GitHub-Media-Type: 161 | - github.v3; format=json 162 | X-GitHub-Request-Id: 163 | - F35A:533C:61F79:7632C:5D77E344 164 | X-OAuth-Scopes: 165 | - admin:org, admin:repo_hook, delete_repo, notifications, read:packages, repo, 166 | write:discussion, write:packages 167 | X-RateLimit-Limit: 168 | - '5000' 169 | X-RateLimit-Remaining: 170 | - '4998' 171 | X-RateLimit-Reset: 172 | - '1568141652' 173 | X-XSS-Protection: 174 | - 1; mode=block 175 | status: 176 | code: 200 177 | message: OK 178 | version: 1 179 | -------------------------------------------------------------------------------- /tests/commands/cassettes/test_return_chosen_inputs.yaml: -------------------------------------------------------------------------------- 1 | interactions: 2 | - request: 3 | body: null 4 | headers: 5 | Accept: 6 | - '*/*' 7 | Accept-Encoding: 8 | - gzip, deflate 9 | Connection: 10 | - keep-alive 11 | User-Agent: 12 | - PyGithub/Python 13 | authorization: 14 | - DUMMY 15 | method: GET 16 | uri: https://api.github.com/user/orgs 17 | response: 18 | body: 19 | string: '[]' 20 | headers: 21 | Access-Control-Allow-Origin: 22 | - '*' 23 | Access-Control-Expose-Headers: 24 | - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, 25 | X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, 26 | X-GitHub-Media-Type 27 | Cache-Control: 28 | - private, max-age=60, s-maxage=60 29 | Content-Length: 30 | - '2' 31 | Content-Security-Policy: 32 | - default-src 'none' 33 | Content-Type: 34 | - application/json; charset=utf-8 35 | Date: 36 | - Tue, 31 Dec 2019 19:15:19 GMT 37 | ETag: 38 | - '"40c720907082566afcff28c6fd9d529d"' 39 | Referrer-Policy: 40 | - origin-when-cross-origin, strict-origin-when-cross-origin 41 | Server: 42 | - GitHub.com 43 | Status: 44 | - 200 OK 45 | Strict-Transport-Security: 46 | - max-age=31536000; includeSubdomains; preload 47 | Vary: 48 | - Accept, Authorization, Cookie, X-GitHub-OTP 49 | - Accept-Encoding 50 | X-Accepted-OAuth-Scopes: 51 | - admin:org, read:org, repo, user, write:org 52 | X-Content-Type-Options: 53 | - nosniff 54 | X-Frame-Options: 55 | - deny 56 | X-GitHub-Media-Type: 57 | - github.v3; format=json 58 | X-GitHub-Request-Id: 59 | - F62D:124A:3AD2296:476864B:5E0B9E47 60 | X-OAuth-Scopes: 61 | - repo 62 | X-RateLimit-Limit: 63 | - '5000' 64 | X-RateLimit-Remaining: 65 | - '4999' 66 | X-RateLimit-Reset: 67 | - '1577823319' 68 | X-XSS-Protection: 69 | - 1; mode=block 70 | status: 71 | code: 200 72 | message: OK 73 | - request: 74 | body: null 75 | headers: 76 | Accept: 77 | - '*/*' 78 | Accept-Encoding: 79 | - gzip, deflate 80 | Connection: 81 | - keep-alive 82 | User-Agent: 83 | - PyGithub/Python 84 | authorization: 85 | - DUMMY 86 | method: GET 87 | uri: https://api.github.com/user 88 | response: 89 | body: 90 | string: !!binary | 91 | H4sIAAAAAAAAA52TTWvjMBCG/4vOSeSPTcMall56TaHQLEsvQZYVe1pZEtLYJWv633dkJy0JhcU5 92 | 2RrN++jVaGZg2tZgWMGqN8AlqoDKswWDihXruyTfZOvNghlbqX0Mse3D093vP49avu6y7cM2377u 93 | ckoXvUDh953XlNMgulBwPgVDuqoBm67sgvLSGlQGV9K2vOPnA+77Xz8IUvsTZjyJAlc4ByfSJCdc 94 | 4JeuG2z1lYnp7FFxmXuwWtt3Yly7/s8x/FNIDqd/MPVtEBIO3GKjqHR0nY9YBAg429IoGnj80DNF 95 | TKDn8Kqaa+skI1PvhvwM3CtnR15XBunBIVgz296FmGDW18LAX3ETjMSBGNHYbCOjiMSqpyacrZ5U 96 | A3ceeiGPsSxeSQU91fk24pWcgHh0ipp/R90Qqw6o9qJq44AehA6KRlG0lGA6rReMmtoJczwvSxrl 97 | aXC0lWNxzzuqFUCTOaka8EqU+pNSgj1vua7UIPdTmYpkwU6Bsb9YDHw1/9eKunjck8RFqoVAcpEl 98 | 6c9lmiyT9DldF0leZOsXulHnqm9y8ucsLfKkSDcv7OMfekQVLZMEAAA= 99 | headers: 100 | Access-Control-Allow-Origin: 101 | - '*' 102 | Access-Control-Expose-Headers: 103 | - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, 104 | X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, 105 | X-GitHub-Media-Type 106 | Cache-Control: 107 | - private, max-age=60, s-maxage=60 108 | Content-Encoding: 109 | - gzip 110 | Content-Security-Policy: 111 | - default-src 'none' 112 | Content-Type: 113 | - application/json; charset=utf-8 114 | Date: 115 | - Tue, 31 Dec 2019 19:15:19 GMT 116 | ETag: 117 | - W/"dbf112e2419f6c409b797ce2cf2a1251" 118 | Last-Modified: 119 | - Thu, 03 Oct 2019 21:30:17 GMT 120 | Referrer-Policy: 121 | - origin-when-cross-origin, strict-origin-when-cross-origin 122 | Server: 123 | - GitHub.com 124 | Status: 125 | - 200 OK 126 | Strict-Transport-Security: 127 | - max-age=31536000; includeSubdomains; preload 128 | Transfer-Encoding: 129 | - chunked 130 | Vary: 131 | - Accept, Authorization, Cookie, X-GitHub-OTP 132 | - Accept-Encoding 133 | X-Accepted-OAuth-Scopes: 134 | - '' 135 | X-Content-Type-Options: 136 | - nosniff 137 | X-Frame-Options: 138 | - deny 139 | X-GitHub-Media-Type: 140 | - github.v3; format=json 141 | X-GitHub-Request-Id: 142 | - F62D:124A:3AD229F:476865E:5E0B9E47 143 | X-OAuth-Scopes: 144 | - repo 145 | X-RateLimit-Limit: 146 | - '5000' 147 | X-RateLimit-Remaining: 148 | - '4998' 149 | X-RateLimit-Reset: 150 | - '1577823319' 151 | X-XSS-Protection: 152 | - 1; mode=block 153 | status: 154 | code: 200 155 | message: OK 156 | - request: 157 | body: '{"name": "fake-project", "private": true}' 158 | headers: 159 | Accept: 160 | - '*/*' 161 | Accept-Encoding: 162 | - gzip, deflate 163 | Connection: 164 | - keep-alive 165 | Content-Length: 166 | - '41' 167 | Content-Type: 168 | - application/json 169 | User-Agent: 170 | - PyGithub/Python 171 | authorization: 172 | - DUMMY 173 | method: POST 174 | uri: https://api.github.com/user/repos 175 | response: 176 | body: 177 | string: '{"id":231137073,"node_id":"MDEwOlJlcG9zaXRvcnkyMzExMzcwNzM=","name":"fake-project","full_name":"dkit-tester/fake-project","private":true,"owner":{"login":"dkit-tester","id":56037257,"node_id":"MDQ6VXNlcjU2MDM3MjU3","avatar_url":"https://avatars1.githubusercontent.com/u/56037257?v=4","gravatar_id":"","url":"https://api.github.com/users/dkit-tester","html_url":"https://github.com/dkit-tester","followers_url":"https://api.github.com/users/dkit-tester/followers","following_url":"https://api.github.com/users/dkit-tester/following{/other_user}","gists_url":"https://api.github.com/users/dkit-tester/gists{/gist_id}","starred_url":"https://api.github.com/users/dkit-tester/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dkit-tester/subscriptions","organizations_url":"https://api.github.com/users/dkit-tester/orgs","repos_url":"https://api.github.com/users/dkit-tester/repos","events_url":"https://api.github.com/users/dkit-tester/events{/privacy}","received_events_url":"https://api.github.com/users/dkit-tester/received_events","type":"User","site_admin":false},"html_url":"https://github.com/dkit-tester/fake-project","description":null,"fork":false,"url":"https://api.github.com/repos/dkit-tester/fake-project","forks_url":"https://api.github.com/repos/dkit-tester/fake-project/forks","keys_url":"https://api.github.com/repos/dkit-tester/fake-project/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dkit-tester/fake-project/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dkit-tester/fake-project/teams","hooks_url":"https://api.github.com/repos/dkit-tester/fake-project/hooks","issue_events_url":"https://api.github.com/repos/dkit-tester/fake-project/issues/events{/number}","events_url":"https://api.github.com/repos/dkit-tester/fake-project/events","assignees_url":"https://api.github.com/repos/dkit-tester/fake-project/assignees{/user}","branches_url":"https://api.github.com/repos/dkit-tester/fake-project/branches{/branch}","tags_url":"https://api.github.com/repos/dkit-tester/fake-project/tags","blobs_url":"https://api.github.com/repos/dkit-tester/fake-project/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dkit-tester/fake-project/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dkit-tester/fake-project/git/refs{/sha}","trees_url":"https://api.github.com/repos/dkit-tester/fake-project/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dkit-tester/fake-project/statuses/{sha}","languages_url":"https://api.github.com/repos/dkit-tester/fake-project/languages","stargazers_url":"https://api.github.com/repos/dkit-tester/fake-project/stargazers","contributors_url":"https://api.github.com/repos/dkit-tester/fake-project/contributors","subscribers_url":"https://api.github.com/repos/dkit-tester/fake-project/subscribers","subscription_url":"https://api.github.com/repos/dkit-tester/fake-project/subscription","commits_url":"https://api.github.com/repos/dkit-tester/fake-project/commits{/sha}","git_commits_url":"https://api.github.com/repos/dkit-tester/fake-project/git/commits{/sha}","comments_url":"https://api.github.com/repos/dkit-tester/fake-project/comments{/number}","issue_comment_url":"https://api.github.com/repos/dkit-tester/fake-project/issues/comments{/number}","contents_url":"https://api.github.com/repos/dkit-tester/fake-project/contents/{+path}","compare_url":"https://api.github.com/repos/dkit-tester/fake-project/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dkit-tester/fake-project/merges","archive_url":"https://api.github.com/repos/dkit-tester/fake-project/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dkit-tester/fake-project/downloads","issues_url":"https://api.github.com/repos/dkit-tester/fake-project/issues{/number}","pulls_url":"https://api.github.com/repos/dkit-tester/fake-project/pulls{/number}","milestones_url":"https://api.github.com/repos/dkit-tester/fake-project/milestones{/number}","notifications_url":"https://api.github.com/repos/dkit-tester/fake-project/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dkit-tester/fake-project/labels{/name}","releases_url":"https://api.github.com/repos/dkit-tester/fake-project/releases{/id}","deployments_url":"https://api.github.com/repos/dkit-tester/fake-project/deployments","created_at":"2019-12-31T19:15:19Z","updated_at":"2019-12-31T19:15:19Z","pushed_at":"2019-12-31T19:15:20Z","git_url":"git://github.com/dkit-tester/fake-project.git","ssh_url":"git@github.com:dkit-tester/fake-project.git","clone_url":"https://github.com/dkit-tester/fake-project.git","svn_url":"https://github.com/dkit-tester/fake-project","homepage":null,"size":0,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":0,"license":null,"forks":0,"open_issues":0,"watchers":0,"default_branch":"main","permissions":{"admin":true,"push":true,"pull":true},"allow_squash_merge":true,"allow_merge_commit":true,"allow_rebase_merge":true,"network_count":0,"subscribers_count":1}' 178 | headers: 179 | Access-Control-Allow-Origin: 180 | - '*' 181 | Access-Control-Expose-Headers: 182 | - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, 183 | X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, 184 | X-GitHub-Media-Type 185 | Cache-Control: 186 | - private, max-age=60, s-maxage=60 187 | Content-Length: 188 | - '5211' 189 | Content-Security-Policy: 190 | - default-src 'none' 191 | Content-Type: 192 | - application/json; charset=utf-8 193 | Date: 194 | - Tue, 31 Dec 2019 19:15:21 GMT 195 | ETag: 196 | - '"986c6704f7781900108d98bb542929fa"' 197 | Location: 198 | - https://api.github.com/repos/dkit-tester/fake-project 199 | Referrer-Policy: 200 | - origin-when-cross-origin, strict-origin-when-cross-origin 201 | Server: 202 | - GitHub.com 203 | Status: 204 | - 201 Created 205 | Strict-Transport-Security: 206 | - max-age=31536000; includeSubdomains; preload 207 | Vary: 208 | - Accept, Authorization, Cookie, X-GitHub-OTP 209 | - Accept-Encoding 210 | X-Accepted-OAuth-Scopes: 211 | - public_repo, repo 212 | X-Content-Type-Options: 213 | - nosniff 214 | X-Frame-Options: 215 | - deny 216 | X-GitHub-Media-Type: 217 | - github.v3; format=json 218 | X-GitHub-Request-Id: 219 | - F62D:124A:3AD22A6:4768664:5E0B9E47 220 | X-OAuth-Scopes: 221 | - repo 222 | X-RateLimit-Limit: 223 | - '5000' 224 | X-RateLimit-Remaining: 225 | - '4997' 226 | X-RateLimit-Reset: 227 | - '1577823319' 228 | X-XSS-Protection: 229 | - 1; mode=block 230 | status: 231 | code: 201 232 | message: Created 233 | version: 1 234 | -------------------------------------------------------------------------------- /tests/commands/test_integrate.py: -------------------------------------------------------------------------------- 1 | import os 2 | from unittest import mock 3 | 4 | import pytest 5 | 6 | from ..conftest import create_plugin_config 7 | from datakit_github.commands import Integrate 8 | 9 | 10 | TOKEN = os.environ.get('DATAKIT_GITHUB_ACCESS_TOKEN', 'DUMMY') 11 | 12 | 13 | def test_config_missing_error(caplog): 14 | cmd = Integrate(None, None, cmd_name='github integrate') 15 | parsed_args = mock.Mock() 16 | cmd.run(parsed_args) 17 | err_msg = "You must configure a Github API key to use this command!!" 18 | assert err_msg in caplog.text 19 | 20 | 21 | @pytest.mark.vcr() 22 | @pytest.mark.usefixtures('create_readme') 23 | def test_choose_default_account(caplog, plugin_dir): 24 | with mock.patch('datakit_github.commands.integrate.ask', side_effect=['','y', 'y']) as mocked, \ 25 | mock.patch('datakit_github.commands.integrate.Repository.push', return_value=None) as repo_push: 26 | create_plugin_config(plugin_dir, {'github_api_key': TOKEN}) 27 | cmd = Integrate(None, None, cmd_name='github integrate') 28 | parsed_args = mock.Mock() 29 | cmd.run(parsed_args) 30 | assert "(1) zstumgoren" in caplog.text 31 | assert "(3) associatedpress" in caplog.text 32 | assert "Repo created at https://github.com/zstumgoren/fake-project" in caplog.text 33 | assert "First commit made locally and pushed to remote" in caplog.text 34 | assert "View the project on Github at https://github.com/zstumgoren/fake-project" in caplog.text 35 | assert repo_push.call_count == 1 36 | 37 | 38 | @pytest.mark.vcr() 39 | @pytest.mark.usefixtures('create_readme') 40 | def test_choose_org_account_private_error(caplog, plugin_dir): 41 | with mock.patch('datakit_github.commands.integrate.ask', side_effect=['3','y','y']) as mocked, \ 42 | mock.patch('datakit_github.commands.integrate.Repository.push', return_value=None) as repo_push: 43 | create_plugin_config(plugin_dir, {'github_api_key': TOKEN}) 44 | cmd = Integrate(None, None, cmd_name='github integrate') 45 | parsed_args = mock.Mock() 46 | cmd.run(parsed_args) 47 | assert "(1) zstumgoren" in caplog.text 48 | assert "(3) associatedpress" in caplog.text 49 | err_msg = "Visibility can't be private. Please upgrade your subscription to create a new private repository." 50 | assert err_msg in caplog.text 51 | 52 | 53 | @pytest.mark.vcr() 54 | @pytest.mark.usefixtures('create_readme') 55 | def test_choose_org_account_public_repo(caplog, plugin_dir): 56 | with mock.patch('datakit_github.commands.integrate.ask', side_effect=['3','y','n']) as mocked, \ 57 | mock.patch('datakit_github.commands.integrate.Repository.push', return_value=None) as repo_push: 58 | create_plugin_config(plugin_dir, {'github_api_key': TOKEN}) 59 | cmd = Integrate(None, None, cmd_name='github integrate') 60 | parsed_args = mock.Mock() 61 | cmd.run(parsed_args) 62 | assert "(1) zstumgoren" in caplog.text 63 | assert "(3) associatedpress" in caplog.text 64 | assert "Repo created at https://github.com/associatedpress/fake-project" in caplog.text 65 | assert "First commit made locally and pushed to remote" in caplog.text 66 | assert "View the project on Github at https://github.com/associatedpress/fake-project" in caplog.text 67 | assert repo_push.call_count == 1 68 | 69 | 70 | @pytest.mark.vcr() 71 | def test_repo_already_exists_org_account(caplog, plugin_dir): 72 | with mock.patch('datakit_github.commands.integrate.ask', side_effect=['3','y', 'n']) as mocked: 73 | create_plugin_config(plugin_dir, {'github_api_key': TOKEN}) 74 | cmd = Integrate(None, None, cmd_name='github integrate') 75 | parsed_args = mock.Mock() 76 | cmd.run(parsed_args) 77 | assert "ERROR: Failed to create fake-project for associatedpress: name already exists on this account" in caplog.text 78 | 79 | 80 | @pytest.mark.vcr() 81 | def test_repo_already_exists(caplog, plugin_dir): 82 | with mock.patch('datakit_github.commands.integrate.ask', side_effect=['','y', 'y']) as mocked: 83 | create_plugin_config(plugin_dir, {'github_api_key': TOKEN}) 84 | cmd = Integrate(None, None, cmd_name='github integrate') 85 | parsed_args = mock.Mock() 86 | cmd.run(parsed_args) 87 | assert "(1) zstumgoren" in caplog.text 88 | assert "ERROR: Failed to create fake-project for zstumgoren: name already exists on this account" in caplog.text 89 | 90 | 91 | @pytest.mark.vcr() 92 | @pytest.mark.usefixtures('init_repo') 93 | def test_repo_already_initialized(caplog, plugin_dir): 94 | with mock.patch('datakit_github.commands.integrate.ask', side_effect=['','y','y']) as mocked: 95 | create_plugin_config(plugin_dir, {'github_api_key': TOKEN}) 96 | cmd = Integrate(None, None, cmd_name='github integrate') 97 | parsed_args = mock.Mock() 98 | cmd.run(parsed_args) 99 | assert "Repo has already been initialized locally!!" in caplog.text 100 | -------------------------------------------------------------------------------- /tests/commands/test_integrate_basic.py: -------------------------------------------------------------------------------- 1 | import os 2 | from unittest import mock 3 | 4 | import pytest 5 | 6 | from ..conftest import create_plugin_config 7 | from datakit_github.commands import Integrate 8 | 9 | 10 | TOKEN = os.environ.get('DATAKIT_TESTER_GITHUB_ACCESS_TOKEN', 'DUMMY') 11 | 12 | 13 | @pytest.mark.vcr() 14 | @pytest.mark.usefixtures('create_readme') 15 | def test_choose_default_account_basic(caplog, plugin_dir): 16 | with mock.patch('datakit_github.commands.integrate.ask', side_effect=['','y', 'y']) as mocked, \ 17 | mock.patch('datakit_github.commands.integrate.Repository.push', return_value=None) as repo_push: 18 | create_plugin_config(plugin_dir, {'github_api_key': TOKEN}) 19 | cmd = Integrate(None, None, cmd_name='github integrate') 20 | parsed_args = mock.Mock() 21 | cmd.run(parsed_args) 22 | assert "Repo will be created on account: dkit-tester" in caplog.text 23 | assert "Repo created at https://github.com/dkit-tester/fake-project" in caplog.text 24 | assert "First commit made locally and pushed to remote" in caplog.text 25 | assert "View the project on Github at https://github.com/dkit-tester/fake-project" in caplog.text 26 | assert repo_push.call_count == 1 27 | 28 | @pytest.mark.vcr() 29 | @pytest.mark.usefixtures('create_readme') 30 | def test_return_chosen_inputs(plugin_dir): 31 | with mock.patch('datakit_github.commands.integrate.ask', side_effect=['','y', 'y']) as mocked, \ 32 | mock.patch('datakit_github.commands.integrate.Repository.push', return_value=None) as repo_push: 33 | create_plugin_config(plugin_dir, {'github_api_key': TOKEN}) 34 | cmd = Integrate(None, None, cmd_name='github integrate') 35 | parsed_args = mock.Mock() 36 | choices = cmd.run(parsed_args) 37 | assert choices['repo_name'] == 'fake-project' 38 | assert choices['account'] == 'dkit-tester' 39 | assert choices['private_repo'] == True 40 | -------------------------------------------------------------------------------- /tests/conftest.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shutil 3 | import subprocess 4 | 5 | import pytest 6 | from datakit.utils import makedirs, mkdir_p, write_json 7 | 8 | from datakit_github.github_api import GithubApi 9 | from datakit_github.repository import Repository 10 | 11 | 12 | @pytest.fixture(scope='module') 13 | def vcr_config(): 14 | return { 15 | 'filter_headers': [('authorization', 'DUMMY')], 16 | } 17 | 18 | def create_gh_project(project_slug): 19 | token = os.environ.get('DATAKIT_GITHUB_ACCESS_TOKEN', 'DUMMY') 20 | return GithubApi('associatedpress', project_slug, {'api_key': token}) 21 | 22 | 23 | @pytest.fixture 24 | def datakit_home(tmpdir): 25 | return os.path.join(str(tmpdir), '.datakit') 26 | 27 | 28 | @pytest.fixture 29 | def plugin_dir(datakit_home): 30 | return os.path.join(datakit_home, 'plugins/datakit-github') 31 | 32 | 33 | @pytest.fixture 34 | def fake_project(tmpdir): 35 | return os.path.join(tmpdir.strpath, 'fake-project') 36 | 37 | 38 | @pytest.fixture(autouse=True) 39 | def setup(datakit_home, plugin_dir, fake_project, monkeypatch, tmpdir): 40 | mkdir_p(datakit_home) 41 | mkdir_p(plugin_dir) 42 | mkdir_p(fake_project) 43 | monkeypatch.setenv('DATAKIT_HOME', datakit_home) 44 | monkeypatch.chdir(fake_project) 45 | 46 | 47 | @pytest.fixture 48 | def init_repo(): 49 | Repository.init() 50 | 51 | 52 | @pytest.fixture 53 | def create_readme(fake_project): 54 | readme = os.path.join(fake_project, "README.md") 55 | content = "Example readme for a test project" 56 | with open(readme, 'w') as fh: 57 | fh.write(content) 58 | 59 | 60 | @pytest.fixture 61 | def stage_files(): 62 | Repository.add() 63 | 64 | 65 | @pytest.fixture 66 | def create_plugin_config_default(plugin_dir): 67 | config_file = os.path.join(plugin_dir, 'config.json') 68 | config = {'default_template': ''} 69 | write_json(config_file, config) 70 | 71 | 72 | def create_plugin_config(plugin_dir, content): 73 | mkdir_p(plugin_dir) 74 | config_file = os.path.join(plugin_dir, 'config.json') 75 | write_json(config_file, content) 76 | return content 77 | 78 | 79 | def create_project_config(project_root, contents={}): 80 | config_dir = os.path.join(project_root, 'config') 81 | mkdir_p(config_dir) 82 | project_config = os.path.join(config_dir, 'datakit-github.json') 83 | write_json(project_config, contents) 84 | 85 | 86 | def dir_contents(path): 87 | dirs_and_files = [] 88 | for root, subdirs, files in os.walk(path): 89 | for directory in subdirs: 90 | dirs_and_files.append(directory) 91 | for fname in files: 92 | dirs_and_files.append(os.path.join(directory, fname)) 93 | return dirs_and_files 94 | 95 | 96 | def read_fixture(name): 97 | tests_dir = os.path.dirname(__file__) 98 | fixture_pth = os.path.join(tests_dir, "fixtures/{}.json".format(name)) 99 | with open(fixture_pth, 'r') as fh: 100 | return fh.read() 101 | 102 | 103 | def repo_status(): 104 | return subprocess.check_output(['git', 'status']).decode('utf-8') 105 | 106 | 107 | def repo_log(num=1): 108 | return subprocess.check_output(['git', 'log']).decode('utf-8') 109 | -------------------------------------------------------------------------------- /tests/test_github_api.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | import pytest 4 | 5 | from datakit_github.github_api import GithubApi 6 | 7 | 8 | TOKEN = os.environ.get('DATAKIT_GITHUB_ACCESS_TOKEN', 'DUMMY') 9 | 10 | 11 | @pytest.mark.vcr() 12 | def test_accounts(): 13 | expected = [ 14 | 'zstumgoren', 15 | 'PythonJournos', 16 | 'associatedpress', 17 | 'datakit-cli', 18 | 'documentcloud', 19 | 'openelections', 20 | 'overview', 21 | 'stanfordjournalism' 22 | ] 23 | actual = [account.login for account in GithubApi.accounts(TOKEN)] 24 | assert actual == expected 25 | -------------------------------------------------------------------------------- /tests/test_repository.py: -------------------------------------------------------------------------------- 1 | import os 2 | import re 3 | from unittest import mock 4 | 5 | import pytest 6 | from .conftest import repo_status, repo_log 7 | 8 | from datakit_github.repository import Repository 9 | 10 | 11 | def test_init(fake_project): 12 | Repository.init() 13 | assert '.git' in os.listdir(fake_project) 14 | 15 | 16 | @pytest.mark.usefixtures('init_repo', 'create_readme') 17 | def test_add_untracked(fake_project): 18 | p = "Untracked files.*?README.md" 19 | assert re.search(p, repo_status(), re.DOTALL) 20 | Repository.add() 21 | assert "new file: README.md" in repo_status() 22 | 23 | 24 | @pytest.mark.usefixtures( 25 | 'init_repo', 26 | 'create_readme', 27 | 'stage_files' 28 | ) 29 | def test_commit(fake_project): 30 | Repository.commit("Initial commit") 31 | assert 'Initial commit' in repo_log() 32 | 33 | 34 | @pytest.mark.usefixtures('init_repo') 35 | def test_add_remote(): 36 | repo_url = 'git@github.com:associatedpress/datakit-github.git' 37 | with mock.patch('datakit_github.repository.subprocess.check_output') as check_output: 38 | Repository.add_remote(repo_url) 39 | check_output.assert_called_once_with(['git', 'remote', 'add', 'origin', repo_url]) 40 | 41 | 42 | @pytest.mark.usefixtures( 43 | 'init_repo', 44 | 'create_readme', 45 | 'stage_files' 46 | ) 47 | def test_push(): 48 | repo_url = 'git@github.com:associatedpress/datakit-github.git' 49 | patch_target = 'datakit_github.repository.subprocess.check_output' 50 | with mock.patch(patch_target) as check_output: 51 | Repository.commit('Initial commit') 52 | Repository.rename_current_branch('main') 53 | Repository.push() 54 | expected_calls = [ 55 | (['git', 'commit', '-m', 'Initial commit'],), 56 | (['git', 'branch', '--move', 'main'],), 57 | (['git', 'push', '-u', 'origin', 'main'],) 58 | ] 59 | actual_calls = [call[1] for call in check_output.mock_calls] 60 | assert actual_calls == expected_calls 61 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = 3 | py35, 4 | py36, 5 | py37, 6 | py38, 7 | py39, 8 | docs, 9 | flake8 10 | 11 | [base] 12 | basepython = 13 | py35: python3.5 14 | py36: python3.6 15 | py37: python3.7 16 | py38: python3.8 17 | py39: python3.9 18 | 19 | [testenv:docs] 20 | basepython=python 21 | changedir=docs 22 | deps= 23 | datakit-core 24 | sphinx 25 | commands= 26 | sphinx-build -b html -d {envtmpdir}/doctrees . {envtmpdir}/html 27 | 28 | [testenv:flake8] 29 | basepython=python 30 | deps=flake8 31 | commands=flake8 datakit_github 32 | 33 | [testenv] 34 | deps = 35 | -r{toxinidir}/requirements-dev.txt 36 | commands = 37 | pip install -U pip 38 | py.test --vcr-record=none --basetemp={envtmpdir} 39 | passenv = 40 | HOME 41 | 42 | ; If you want to make tox run the tests with the same versions, create a 43 | ; requirements.txt with the pinned versions and uncomment the following lines: 44 | ; deps = 45 | ; -r{toxinidir}/requirements.txt 46 | --------------------------------------------------------------------------------