Skip to content

Commit

Permalink
Allow passed authentication params on init (#41)
Browse files Browse the repository at this point in the history
* Update readme, changelog and setup for dependencies

Signed-off-by: kaosx5s <>

* Add support for passing in the git token on init

Signed-off-by: kaosx5s <>

* Update python-version in workflow

Signed-off-by: kaosx5s <>

* Updates based on PR feedback

Signed-off-by: kaosx5s <>

---------

Signed-off-by: kaosx5s <>
Co-authored-by: Corey Caverly <[email protected]>
  • Loading branch information
kaosx5s and coreycaverly authored Oct 4, 2023
1 parent 5d59323 commit e9f1eb1
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 22 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/python-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.7, 3.8]
python-version: [3.7, 3.8, 3.9, '3.10', 3.11]

steps:
- uses: actions/checkout@v1
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com),
and this project adheres to [Semantic Versioning](https://semver.org).

## [3.5.0] - 2023-05-16
### Added
- Added support to pass in a github token, username and password as named parameters

## [3.4.0] - 2023-02-24
### Added
- Added method to return the github client

## [3.3.0] - 2022-05-12
### Added
- Added support for serialization options when dumping a file

## [3.2.0] - 2021-03-26
### Added
- Added plain text file support
Expand Down
35 changes: 30 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,24 +130,48 @@ if __name__ == '__main__':

# Dependencies
- `config.yaml` (required) - list of repositories you wish to modify
- `GIT_USERNAME` (required) - your Github username
- `GIT_PASSWORD` (required) - Github personal access token that grants write access to the specified repositories
- `GIT_USERNAME` (optional) - your Github username
- `GIT_PASSWORD` (optional) - your Github password or Personal Access Token
- `GIT_TOKEN` (optional) - Github Personal Access Token that grants write access to the specified repositories

# Authentication
Two methods of authentication are available:
- Using a Personal Access Token
- Using a Github Username & Password

A Github Personal Access Token, Github Username and Github Password can also be passed in via the `token=`, `username=` and `password=` named parameters. The passed value will always take precedence over any environment variable. (Added in `3.5.0`)

## Authentication - Personal Access Token
A Personal Access Token can be used in two ways:
- Setting the `GIT_TOKEN` environment variable
- Passing the `token=` named parameter

The Personal Access Token must have `write` access to any specified repositories you wish to submit changes to.

## Authentication - Github Username & Password
A Github Username and Password combination can be used in two ways:
- Setting the `GIT_USERNAME` and `GIT_PASSWORD` environment variables
- Passing the `username=` and `password=` parameters

The user must have `write` access to any specified repositories you wish to submit changes to.

The `GIT_PASSWORD` or `password=` may also contain a Personal Access Token instead of the account password.

# Development
The simplest way to hit the ground running if you want to contribute with code is using docker.

Launch a python container
```
```shell
localhost$ docker run --rm -it -v $(pwd):$(pwd) -w $(pwd) python:3.7-stretch bash
```

Install the project and test dependencies in developer mode
```
```shell
container# pip install -e .[test]
```

Run the tests
```
```shell
container# pytest
=========================================== test session starts ============================================
platform linux -- Python 3.7.1, pytest-4.5.0, py-1.8.0, pluggy-0.11.0
Expand All @@ -170,3 +194,4 @@ collected 33 items
## Contributors
- [Jeremy Chavez](https://github.com/kaosx5s)
- [Etienne Grignon](https://github.com/sharpyy)
- [Anshul Vohra](https://github.com/AnshulV98)
18 changes: 10 additions & 8 deletions gordian/repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
import datetime
import logging
import os
import sys
import time
from retry import retry
from gordian.files import *
from gordian.files.plaintext_file import PlainTextFile
Expand All @@ -16,7 +14,7 @@

class Repo:

def __init__(self, repo_name, github_api_url=None, branch=None, github=None, files=None, semver_label=None, target_branch='master', fork=False):
def __init__(self, repo_name, github_api_url=None, branch=None, github=None, files=None, semver_label=None, target_branch='master', fork=False, token=None, username=None, password=None):
if github_api_url is None:
self.github_api_url = BASE_URL
else:
Expand All @@ -25,12 +23,16 @@ def __init__(self, repo_name, github_api_url=None, branch=None, github=None, fil
if github is not None:
self._github = github
else:
if "GIT_TOKEN" in os.environ:
logger.debug('Using git token')
self._github = Github(base_url=self.github_api_url, login_or_token=os.environ['GIT_TOKEN'])
username = os.getenv('GIT_USERNAME', username)
password = os.getenv('GIT_PASSWORD', password)
token = os.getenv('GIT_TOKEN', token)

if token:
logger.debug('Using git token for authentication')
self._github = Github(base_url=self.github_api_url, login_or_token=token)
else:
logger.debug('Using git username and password')
self._github = Github(base_url=self.github_api_url, login_or_token=os.environ['GIT_USERNAME'], password=os.environ['GIT_PASSWORD'])
logger.debug('Using git username and password for authentication')
self._github = Github(base_url=self.github_api_url, login_or_token=username, password=password)

if files is None:
files = []
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
setup_reqs = ["pytest", "pytest-cov", "pytest-runner", "flake8"]
setuptools.setup(
name="gordian",
version="3.4.0",
version="3.5.0",
author="Intuit",
author_email="[email protected]",
description="A tool to search and replace files in a Git repo",
Expand Down
57 changes: 50 additions & 7 deletions tests/test_repo.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import unittest
import pytest
import os
from gordian.repo import Repo
from unittest.mock import MagicMock, patch, call
from gordian.files import YamlFile
Expand Down Expand Up @@ -86,15 +87,15 @@ def test_get_files(self):
self.repo._source_repo.get_contents.assert_has_calls([call('', 'refs/heads/target'), call('directory', 'refs/heads/target')])
self.assertEquals(self.repo.files, [repository_file])

def test__set_target_branch(self):
def test_set_target_branch(self):
self.repo._set_target_branch('master')
self.assertEqual(self.repo.source_branch, 'refs/heads/master')

def test__set_target_branch_source_branch(self):
def test_set_target_branch_source_branch(self):
self.repo._set_target_branch('master', 'something')
self.assertEqual(self.repo.source_branch, 'refs/heads/something')

def test__set_target_branch_reset_file_cache(self):
def test_set_target_branch_reset_file_cache(self):
self.repo._set_target_branch('master')
cached_files = ['cached_file', 'cached_file', 'cached_file']
self.repo.files = cached_files
Expand Down Expand Up @@ -127,29 +128,71 @@ def test_create_pr_no_labels(self):
pr.set_labels.assert_not_called()
repo._source_repo.create_pull.assert_not_called()

def test__get_new_version_major(self):
def test_get_new_version_major(self):
version_file = MagicMock()
version_file.decoded_content = '1.2.3'.encode('utf-8')
self.repo.version_file = version_file
self.repo.semver_label = 'major'
self.repo._get_new_version()
self.assertEqual(self.repo.new_version, '2.0.0')

def test__get_new_version_minor(self):
def test_get_new_version_minor(self):
version_file = MagicMock()
version_file.decoded_content = '1.2.3'.encode('utf-8')
self.repo.version_file = version_file
self.repo.semver_label = 'minor'
self.repo._get_new_version()
self.assertEqual(self.repo.new_version, '1.3.0')

def test__get_new_version_patch(self):
def test_get_new_version_patch(self):
version_file = MagicMock()
version_file.decoded_content = '1.2.3'.encode('utf-8')
self.repo.version_file = version_file
self.repo.semver_label = 'patch'
self.repo._get_new_version()
self.assertEqual(self.repo.new_version, '1.2.4')

@patch('gordian.repo.Github')
def test_init_with_passed_token(self, mock_git):
Repo('test_repo', token='abcdef')
args = {'login_or_token': 'abcdef', 'base_url': 'https://api.github.com'}
mock_git.assert_called_with(**args)

@patch.dict(os.environ, {'GIT_TOKEN': '12345'})
@patch('gordian.repo.Github')
def test_init_with_token_from_env(self, mock_git):
Repo('test_repo')
args = {'login_or_token': '12345', 'base_url': 'https://api.github.com'}

mock_git.assert_called_with(**args)

@patch.dict(os.environ, {'GIT_USERNAME': 'test-user', 'GIT_PASSWORD': 'test-pass'})
@patch('gordian.repo.Github')
def test_init_with_user_pass_env(self, mock_git):
Repo('test_repo')
args = {'login_or_token':'test-user', 'password':'test-pass', 'base_url': 'https://api.github.com'}

mock_git.assert_called_with(**args)

@patch('gordian.repo.Github')
def test_create_file(self, mock_git):
repo = Repo('test_repo', github=mock_git)
repo.create_file('test', 'test', 'test file create')

repo._source_repo.create_file.assert_called_once()
self.assertTrue(repo.dirty)

@patch('gordian.repo.Github')
def test_delete_file(self, mock_git):
mock_file = MagicMock()
repo = Repo('test_repo', github=mock_git)
repo.delete_file(mock_file, 'test file delete')

repo._source_repo.delete_file.assert_called_once()
self.assertTrue(repo.dirty)

def test__get_github_client(self):
self.assertIsNotNone(self.repo.get_github_client)
repo = Repo('test_repo', branch='', github=self.mock_git)

self.assertIsNotNone(repo.get_github_client())
self.assertEqual(repo.get_github_client(), self.mock_git)

0 comments on commit e9f1eb1

Please sign in to comment.