From 92151b22b5b03b3d529caf1865a2e35738a2f3d2 Mon Sep 17 00:00:00 2001 From: savenger Date: Fri, 3 Mar 2017 13:57:46 +0100 Subject: [PATCH 01/15] Time tracking (#222) * Added gitlab time tracking features - get/set/remove estimated time per issue - get/set/remove time spent per issue * Added documentation for time tracking functions --- docs/gl_objects/issues.py | 20 ++++++++++++ docs/gl_objects/issues.rst | 31 +++++++++++++++++++ gitlab/exceptions.py | 4 +++ gitlab/objects.py | 63 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 118 insertions(+) diff --git a/docs/gl_objects/issues.py b/docs/gl_objects/issues.py index ad48dc80e..df13c20da 100644 --- a/docs/gl_objects/issues.py +++ b/docs/gl_objects/issues.py @@ -77,3 +77,23 @@ # project issue todo issue.todo() # end project issue todo + +# project issue time tracking stats +issue.time_stats() +# end project issue time tracking stats + +# project issue set time estimate +issue.set_time_estimate({'duration': '3h30m'}) +# end project issue set time estimate + +# project issue reset time estimate +issue.reset_time_estimate() +# end project issue reset time estimate + +# project issue set time spent +issue.add_time_spent({'duration': '3h30m'}) +# end project issue set time spent + +# project issue reset time spent +issue.reset_time_spent() +# end project issue reset time spent diff --git a/docs/gl_objects/issues.rst b/docs/gl_objects/issues.rst index d4cbf003d..27724b8b3 100644 --- a/docs/gl_objects/issues.rst +++ b/docs/gl_objects/issues.rst @@ -104,3 +104,34 @@ Make an issue as todo: .. literalinclude:: issues.py :start-after: # project issue todo :end-before: # end project issue todo + +Get time tracking stats: + +.. literalinclude:: issues.py + :start-after: # project issue time tracking stats + :end-before: # end project time tracking stats + +Set a time estimate for an issue: + +.. literalinclude:: issues.py + :start-after: # project issue set time estimate + :end-before: # end project set time estimate + +Reset a time estimate for an issue: + +.. literalinclude:: issues.py + :start-after: # project issue reset time estimate + :end-before: # end project reset time estimate + +Add spent time for an issue: + +.. literalinclude:: issues.py + :start-after: # project issue set time spent + :end-before: # end project set time spent + +Reset spent time for an issue: + +.. literalinclude:: issues.py + :start-after: # project issue reset time spent + :end-before: # end project reset time spent + diff --git a/gitlab/exceptions.py b/gitlab/exceptions.py index 1d1f477b9..11bbe26cb 100644 --- a/gitlab/exceptions.py +++ b/gitlab/exceptions.py @@ -143,6 +143,10 @@ class GitlabTodoError(GitlabOperationError): pass +class GitlabTimeTrackingError(GitlabOperationError): + pass + + def raise_error_from_response(response, error, expected_code=200): """Tries to parse gitlab error message from response and raises error. diff --git a/gitlab/objects.py b/gitlab/objects.py index ea40b6f7d..efe75d0a6 100644 --- a/gitlab/objects.py +++ b/gitlab/objects.py @@ -1523,6 +1523,69 @@ def todo(self, **kwargs): r = self.gitlab._raw_post(url, **kwargs) raise_error_from_response(r, GitlabTodoError, [201, 304]) + def time_stats(self, **kwargs): + """Get time stats for the issue. + + Raises: + GitlabConnectionError: If the server cannot be reached. + """ + url = ('/projects/%(project_id)s/issues/%(issue_id)s/time_stats' % + {'project_id': self.project_id, 'issue_id': self.id}) + r = self.gitlab._raw_get(url, **kwargs) + raise_error_from_response(r, GitlabGetError) + return r.json() + + def time_estimate(self, **kwargs): + """Set an estimated time of work for the issue. + + Raises: + GitlabConnectionError: If the server cannot be reached. + """ + url = ('/projects/%(project_id)s/issues/%(issue_id)s/time_estimate' % + {'project_id': self.project_id, 'issue_id': self.id}) + r = self.gitlab._raw_post(url, **kwargs) + raise_error_from_response(r, GitlabTimeTrackingError, 201) + return r.json() + + def reset_time_estimate(self, **kwargs): + """Resets estimated time for the issue to 0 seconds. + + Raises: + GitlabConnectionError: If the server cannot be reached. + """ + url = ('/projects/%(project_id)s/issues/%(issue_id)s/' + 'reset_time_estimate' % + {'project_id': self.project_id, 'issue_id': self.id}) + r = self.gitlab._raw_post(url, **kwargs) + raise_error_from_response(r, GitlabTimeTrackingError, 200) + return r.json() + + def add_spent_time(self, **kwargs): + """Set an estimated time of work for the issue. + + Raises: + GitlabConnectionError: If the server cannot be reached. + """ + url = ('/projects/%(project_id)s/issues/%(issue_id)s/' + 'reset_spent_time' % + {'project_id': self.project_id, 'issue_id': self.id}) + r = self.gitlab._raw_post(url, **kwargs) + raise_error_from_response(r, GitlabTimeTrackingError, 200) + return r.json() + + def reset_spent_time(self, **kwargs): + """Set an estimated time of work for the issue. + + Raises: + GitlabConnectionError: If the server cannot be reached. + """ + url = ('/projects/%(project_id)s/issues/%(issue_id)s/' + 'add_spent_time' % + {'project_id': self.project_id, 'issue_id': self.id}) + r = self.gitlab._raw_post(url, **kwargs) + raise_error_from_response(r, GitlabTimeTrackingError, 200) + return r.json() + class ProjectIssueManager(BaseManager): obj_cls = ProjectIssue From 37ee7ea6a9354c0ea5bd618d48b4a2a3ddbc950c Mon Sep 17 00:00:00 2001 From: Alexander Skiba Date: Thu, 9 Mar 2017 10:48:21 +0100 Subject: [PATCH 02/15] Changelog: improvements. Fixes #229 (#230) + change indentation so bullet points are not treated as quote + add links to releases + add dates to releases + use releases as headers --- ChangeLog | 354 ------------------------------------------- ChangeLog.rst | 407 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 407 insertions(+), 354 deletions(-) delete mode 100644 ChangeLog create mode 100644 ChangeLog.rst diff --git a/ChangeLog b/ChangeLog deleted file mode 100644 index 14415f9ac..000000000 --- a/ChangeLog +++ /dev/null @@ -1,354 +0,0 @@ -Version 0.19 - - * Update project.archive() docs - * Support the scope attribute in runners.list() - * Add support for project runners - * Add support for commit creation - * Fix install doc - * Add builds-email and pipelines-email services - * Deploy keys: rework enable/disable - * Document the dynamic aspect of objects - * Add pipeline_events to ProjectHook attrs - * Add due_date attribute to ProjectIssue - * Handle settings.domain_whitelist, partly - * {Project,Group}Member: support expires_at attribute - -Version 0.18 - - * Fix JIRA service editing for GitLab 8.14+ - * Add jira_issue_transition_id to the JIRA service optional fields - * Added support for Snippets (new API in Gitlab 8.15) - * [docs] update pagination section - * [docs] artifacts example: open file in wb mode - * [CLI] ignore empty arguments - * [CLI] Fix wrong use of arguments - * [docs] Add doc for snippets - * Fix duplicated data in API docs - * Update known attributes for projects - * sudo: always use strings - -Version 0.17 - - * README: add badges for pypi and RTD - * Fix ProjectBuild.play (raised error on success) - * Pass kwargs to the object factory - * Add .tox to ignore to respect default tox settings - * Convert response list to single data source for iid requests - * Add support for boards API - * Add support for Gitlab.version() - * Add support for broadcast messages API - * Add support for the notification settings API - * Don't overwrite attributes returned by the server - * Fix bug when retrieving changes for merge request - * Feature: enable / disable the deploy key in a project - * Docs: add a note for python 3.5 for file content update - * ProjectHook: support the token attribute - * Rework the API documentation - * Fix docstring for http_{username,password} - * Build managers on demand on GitlabObject's - * API docs: add managers doc in GitlabObject's - * Sphinx ext: factorize the build methods - * Implement __repr__ for gitlab objects - * Add a 'report a bug' link on doc - * Remove deprecated methods - * Implement merge requests diff support - * Make the manager objects creation more dynamic - * Add support for templates API - * Add attr 'created_at' to ProjectIssueNote - * Add attr 'updated_at' to ProjectIssue - * CLI: add support for project all --all - * Add support for triggering a new build - * Rework requests arguments (support latest requests release) - * Fix `should_remove_source_branch` - -Version 0.16 - - * Add the ability to fork to a specific namespace - * JIRA service - add api_url to optional attributes - * Fix bug: Missing coma concatenates array values - * docs: branch protection notes - * Create a project in a group - * Add only_allow_merge_if_build_succeeds option to project objects - * Add support for --all in CLI - * Fix examples for file modification - * Use the plural merge_requests URL everywhere - * Rework travis and tox setup - * Workaround gitlab setup failure in tests - * Add ProjectBuild.erase() - * Implement ProjectBuild.play() - -Version 0.15.1 - - * docs: improve the pagination section - * Fix and test pagination - * 'path' is an existing gitlab attr, don't use it as method argument - -Version 0.15 - - * Add a basic HTTP debug method - * Run more tests in travis - * Fix fork creation documentation - * Add more API examples in docs - * Update the ApplicationSettings attributes - * Implement the todo API - * Add sidekiq metrics support - * Move the constants at the gitlab root level - * Remove methods marked as deprecated 7 months ago - * Refactor the Gitlab class - * Remove _get_list_or_object() and its tests - * Fix canGet attribute (typo) - * Remove unused ProjectTagReleaseManager class - * Add support for project services API - * Add support for project pipelines - * Add support for access requests - * Add support for project deployments - -Version 0.14 - - * Remove 'next_url' from kwargs before passing it to the cls constructor. - * List projects under group - * Add support for subscribe and unsubscribe in issues - * Project issue: doc and CLI for (un)subscribe - * Added support for HTTP basic authentication - * Add support for build artifacts and trace - * --title is a required argument for ProjectMilestone - * Commit status: add optional context url - * Commit status: optional get attrs - * Add support for commit comments - * Issues: add optional listing parameters - * Issues: add missing optional listing parameters - * Project issue: proper update attributes - * Add support for project-issue move - * Update ProjectLabel attributes - * Milestone: optional listing attrs - * Add support for namespaces - * Add support for label (un)subscribe - * MR: add (un)subscribe support - * Add `note_events` to project hooks attributes - * Add code examples for a bunch of resources - * Implement user emails support - * Project: add VISIBILITY_* constants - * Fix the Project.archive call - * Implement archive/unarchive for a projet - * Update ProjectSnippet attributes - * Fix ProjectMember update - * Implement sharing project with a group - * Implement CLI for project archive/unarchive/share - * Implement runners global API - * Gitlab: add managers for build-related resources - * Implement ProjectBuild.keep_artifacts - * Allow to stream the downloads when appropriate - * Groups can be updated - * Replace Snippet.Content() with a new content() method - * CLI: refactor _die() - * Improve commit statuses and comments - * Add support from listing group issues - * Added a new project attribute to enable the container registry. - * Add a contributing section in README - * Add support for global deploy key listing - * Add support for project environments - * MR: get list of changes and commits - * Fix the listing of some resources - * MR: fix updates - * Handle empty messages from server in exceptions - * MR (un)subscribe: don't fail if state doesn't change - * MR merge(): update the object - -Version 0.13 - - * Add support for MergeRequest validation - * MR: add support for cancel_merge_when_build_succeeds - * MR: add support for closes_issues - * Add "external" parameter for users - * Add deletion support for issues and MR - * Add missing group creation parameters - * Add a Session instance for all HTTP requests - * Enable updates on ProjectIssueNotes - * Add support for Project raw_blob - * Implement project compare - * Implement project contributors - * Drop the next_url attribute when listing - * Remove unnecessary canUpdate property from ProjectIssuesNote - * Add new optional attributes for projects - * Enable deprecation warnings for gitlab only - * Rework merge requests update - * Rework the Gitlab.delete method - * ProjectFile: file_path is required for deletion - * Rename some methods to better match the API URLs - * Deprecate the file_* methods in favor of the files manager - * Implement star/unstar for projects - * Implement list/get licenses - * Manage optional parameters for list() and get() - -Version 0.12.2 - - * Add new `ProjectHook` attributes - * Add support for user block/unblock - * Fix GitlabObject creation in _custom_list - * Add support for more CLI subcommands - * Add some unit tests for CLI - * Add a coverage tox env - * Define GitlabObject.as_dict() to dump object as a dict - * Define GitlabObject.__eq__() and __ne__() equivalence methods - * Define UserManager.search() to search for users - * Define UserManager.get_by_username() to get a user by username - * Implement "user search" CLI - * Improve the doc for UserManager - * CLI: implement user get-by-username - * Re-implement _custom_list in the Gitlab class - * Fix the 'invalid syntax' error on Python 3.2 - * Gitlab.update(): use the proper attributes if defined - -Version 0.12.1 - - * Fix a broken upload to pypi - -Version 0.12 - - * Improve documentation - * Improve unit tests - * Improve test scripts - * Skip BaseManager attributes when encoding to JSON - * Fix the json() method for python 3 - * Add Travis CI support - * Add a decode method for ProjectFile - * Make connection exceptions more explicit - * Fix ProjectLabel get and delete - * Implement ProjectMilestone.issues() - * ProjectTag supports deletion - * Implement setting release info on a tag - * Implement project triggers support - * Implement project variables support - * Add support for application settings - * Fix the 'password' requirement for User creation - * Add sudo support - * Fix project update - * Fix Project.tree() - * Add support for project builds - -Version 0.11.1 - - * Fix discovery of parents object attrs for managers - * Support setting commit status - * Support deletion without getting the object first - * Improve the documentation - -Version 0.11 - - * functional_tests.sh: support python 2 and 3 - * Add a get method for GitlabObject - * CLI: Add the -g short option for --gitlab - * Provide a create method for GitlabObject's - * Rename the _created attribute _from_api - * More unit tests - * CLI: fix error when arguments are missing (python 3) - * Remove deprecated methods - * Implement managers to get access to resources - * Documentation improvements - * Add fork project support - * Deprecate the "old" Gitlab methods - * Add support for groups search - -Version 0.10 - - * Implement pagination for list() (#63) - * Fix url when fetching a single MergeRequest - * Add support to update MergeRequestNotes - * API: Provide a Gitlab.from_config method - * setup.py: require requests>=1 (#69) - * Fix deletion of object not using 'id' as ID (#68) - * Fix GET/POST for project files - * Make 'confirm' an optional attribute for user creation - * Python 3 compatibility fixes - * Add support for group members update (#73) - -Version 0.9.2 - - * CLI: fix the update and delete subcommands (#62) - -Version 0.9.1 - - * Fix the setup.py script - -Version 0.9 - - * Implement argparse libray for parsing argument on CLI - * Provide unit tests and (a few) functional tests - * Provide PEP8 tests - * Use tox to run the tests - * CLI: provide a --config-file option - * Turn the gitlab module into a proper package - * Allow projects to be updated - * Use more pythonic names for some methods - * Deprecate some Gitlab object methods: - - raw* methods should never have been exposed; replace them with _raw_* - methods - - setCredentials and setToken are replaced with set_credentials and - set_token - * Sphinx: don't hardcode the version in conf.py - -Version 0.8 - - * Better python 2.6 and python 3 support - * Timeout support in HTTP requests - * Gitlab.get() raised GitlabListError instead of GitlabGetError - * Support api-objects which don't have id in api response - * Add ProjectLabel and ProjectFile classes - * Moved url attributes to separate list - * Added list for delete attributes - -Version 0.7 - - * Fix license classifier in setup.py - * Fix encoding error when printing to redirected output - * Fix encoding error when updating with redirected output - * Add support for UserKey listing and deletion - * Add support for branches creation and deletion - * Support state_event in ProjectMilestone (#30) - * Support namespace/name for project id (#28) - * Fix handling of boolean values (#22) - -Version 0.6 - - * IDs can be unicode (#15) - * ProjectMember: constructor should not create a User object - * Add support for extra parameters when listing all projects (#12) - * Projects listing: explicitly define arguments for pagination - -Version 0.5 - - * Add SSH key for user - * Fix comments - * Add support for project events - * Support creation of projects for users - * Project: add methods for create/update/delete files - * Support projects listing: search, all, owned - * System hooks can't be updated - * Project.archive(): download tarball of the project - * Define new optional attributes for user creation - * Provide constants for access permissions in groups - -Version 0.4 - - * Fix strings encoding (Closes #6) - * Allow to get a project commit (GitLab 6.1) - * ProjectMergeRequest: fix Note() method - * Gitlab 6.1 methods: diff, blob (commit), tree, blob (project) - * Add support for Gitlab 6.1 group members - -Version 0.3 - - * Use PRIVATE-TOKEN header for passing the auth token - * provide a AUTHORS file - * cli: support ssl_verify config option - * Add ssl_verify option to Gitlab object. Defauls to True - * Correct url for merge requests API. - -Version 0.2 - - * provide a pip requirements.txt - * drop some debug statements - -Version 0.1 - - * Initial release diff --git a/ChangeLog.rst b/ChangeLog.rst new file mode 100644 index 000000000..751023239 --- /dev/null +++ b/ChangeLog.rst @@ -0,0 +1,407 @@ +python-gitlab Changelog +======================= + +Version 0.19_: - 2017-02-21 +--------------------------- + +* Update project.archive() docs +* Support the scope attribute in runners.list() +* Add support for project runners +* Add support for commit creation +* Fix install doc +* Add builds-email and pipelines-email services +* Deploy keys: rework enable/disable +* Document the dynamic aspect of objects +* Add pipeline_events to ProjectHook attrs +* Add due_date attribute to ProjectIssue +* Handle settings.domain_whitelist, partly +* {Project,Group}Member: support expires_at attribute + +Version 0.18_: - 2016-12-27 +--------------------------- + +* Fix JIRA service editing for GitLab 8.14+ +* Add jira_issue_transition_id to the JIRA service optional fields +* Added support for Snippets (new API in Gitlab 8.15) +* [docs] update pagination section +* [docs] artifacts example: open file in wb mode +* [CLI] ignore empty arguments +* [CLI] Fix wrong use of arguments +* [docs] Add doc for snippets +* Fix duplicated data in API docs +* Update known attributes for projects +* sudo: always use strings + +Version 0.17_: - 2016-12-02 +--------------------------- + +* README: add badges for pypi and RTD +* Fix ProjectBuild.play (raised error on success) +* Pass kwargs to the object factory +* Add .tox to ignore to respect default tox settings +* Convert response list to single data source for iid requests +* Add support for boards API +* Add support for Gitlab.version() +* Add support for broadcast messages API +* Add support for the notification settings API +* Don't overwrite attributes returned by the server +* Fix bug when retrieving changes for merge request +* Feature: enable / disable the deploy key in a project +* Docs: add a note for python 3.5 for file content update +* ProjectHook: support the token attribute +* Rework the API documentation +* Fix docstring for http_{username,password} +* Build managers on demand on GitlabObject's +* API docs: add managers doc in GitlabObject's +* Sphinx ext: factorize the build methods +* Implement __repr__ for gitlab objects +* Add a 'report a bug' link on doc +* Remove deprecated methods +* Implement merge requests diff support +* Make the manager objects creation more dynamic +* Add support for templates API +* Add attr 'created_at' to ProjectIssueNote +* Add attr 'updated_at' to ProjectIssue +* CLI: add support for project all --all +* Add support for triggering a new build +* Rework requests arguments (support latest requests release) +* Fix `should_remove_source_branch` + +Version 0.16_: - 2016-10-16 +--------------------------- + +* Add the ability to fork to a specific namespace +* JIRA service - add api_url to optional attributes +* Fix bug: Missing coma concatenates array values +* docs: branch protection notes +* Create a project in a group +* Add only_allow_merge_if_build_succeeds option to project objects +* Add support for --all in CLI +* Fix examples for file modification +* Use the plural merge_requests URL everywhere +* Rework travis and tox setup +* Workaround gitlab setup failure in tests +* Add ProjectBuild.erase() +* Implement ProjectBuild.play() + +Version 0.15.1_: - 2016-10-16 +----------------------------- + +* docs: improve the pagination section +* Fix and test pagination +* 'path' is an existing gitlab attr, don't use it as method argument + +Version 0.15_: - 2016-08-28 +--------------------------- + +* Add a basic HTTP debug method +* Run more tests in travis +* Fix fork creation documentation +* Add more API examples in docs +* Update the ApplicationSettings attributes +* Implement the todo API +* Add sidekiq metrics support +* Move the constants at the gitlab root level +* Remove methods marked as deprecated 7 months ago +* Refactor the Gitlab class +* Remove _get_list_or_object() and its tests +* Fix canGet attribute (typo) +* Remove unused ProjectTagReleaseManager class +* Add support for project services API +* Add support for project pipelines +* Add support for access requests +* Add support for project deployments + +Version 0.14_: - 2016-08-07 +--------------------------- + +* Remove 'next_url' from kwargs before passing it to the cls constructor. +* List projects under group +* Add support for subscribe and unsubscribe in issues +* Project issue: doc and CLI for (un)subscribe +* Added support for HTTP basic authentication +* Add support for build artifacts and trace +* --title is a required argument for ProjectMilestone +* Commit status: add optional context url +* Commit status: optional get attrs +* Add support for commit comments +* Issues: add optional listing parameters +* Issues: add missing optional listing parameters +* Project issue: proper update attributes +* Add support for project-issue move +* Update ProjectLabel attributes +* Milestone: optional listing attrs +* Add support for namespaces +* Add support for label (un)subscribe +* MR: add (un)subscribe support +* Add `note_events` to project hooks attributes +* Add code examples for a bunch of resources +* Implement user emails support +* Project: add VISIBILITY_* constants +* Fix the Project.archive call +* Implement archive/unarchive for a projet +* Update ProjectSnippet attributes +* Fix ProjectMember update +* Implement sharing project with a group +* Implement CLI for project archive/unarchive/share +* Implement runners global API +* Gitlab: add managers for build-related resources +* Implement ProjectBuild.keep_artifacts +* Allow to stream the downloads when appropriate +* Groups can be updated +* Replace Snippet.Content() with a new content() method +* CLI: refactor _die() +* Improve commit statuses and comments +* Add support from listing group issues +* Added a new project attribute to enable the container registry. +* Add a contributing section in README +* Add support for global deploy key listing +* Add support for project environments +* MR: get list of changes and commits +* Fix the listing of some resources +* MR: fix updates +* Handle empty messages from server in exceptions +* MR (un)subscribe: don't fail if state doesn't change +* MR merge(): update the object + +Version 0.13_: - 2016-05-16 +--------------------------- + +* Add support for MergeRequest validation +* MR: add support for cancel_merge_when_build_succeeds +* MR: add support for closes_issues +* Add "external" parameter for users +* Add deletion support for issues and MR +* Add missing group creation parameters +* Add a Session instance for all HTTP requests +* Enable updates on ProjectIssueNotes +* Add support for Project raw_blob +* Implement project compare +* Implement project contributors +* Drop the next_url attribute when listing +* Remove unnecessary canUpdate property from ProjectIssuesNote +* Add new optional attributes for projects +* Enable deprecation warnings for gitlab only +* Rework merge requests update +* Rework the Gitlab.delete method +* ProjectFile: file_path is required for deletion +* Rename some methods to better match the API URLs +* Deprecate the file_* methods in favor of the files manager +* Implement star/unstar for projects +* Implement list/get licenses +* Manage optional parameters for list() and get() + +Version 0.12.2_: - 2016-03-19 +----------------------------- + +* Add new `ProjectHook` attributes +* Add support for user block/unblock +* Fix GitlabObject creation in _custom_list +* Add support for more CLI subcommands +* Add some unit tests for CLI +* Add a coverage tox env +* Define GitlabObject.as_dict() to dump object as a dict +* Define GitlabObject.__eq__() and __ne__() equivalence methods +* Define UserManager.search() to search for users +* Define UserManager.get_by_username() to get a user by username +* Implement "user search" CLI +* Improve the doc for UserManager +* CLI: implement user get-by-username +* Re-implement _custom_list in the Gitlab class +* Fix the 'invalid syntax' error on Python 3.2 +* Gitlab.update(): use the proper attributes if defined + +Version 0.12.1_: - 2016-02-03 +----------------------------- + +* Fix a broken upload to pypi + +Version 0.12_: - 2016-02-03 +--------------------------- + +* Improve documentation +* Improve unit tests +* Improve test scripts +* Skip BaseManager attributes when encoding to JSON +* Fix the json() method for python 3 +* Add Travis CI support +* Add a decode method for ProjectFile +* Make connection exceptions more explicit +* Fix ProjectLabel get and delete +* Implement ProjectMilestone.issues() +* ProjectTag supports deletion +* Implement setting release info on a tag +* Implement project triggers support +* Implement project variables support +* Add support for application settings +* Fix the 'password' requirement for User creation +* Add sudo support +* Fix project update +* Fix Project.tree() +* Add support for project builds + +Version 0.11.1_: - 2016-01-17 +----------------------------- + +* Fix discovery of parents object attrs for managers +* Support setting commit status +* Support deletion without getting the object first +* Improve the documentation + +Version 0.11_: - 2016-01-09 +--------------------------- + +* functional_tests.sh: support python 2 and 3 +* Add a get method for GitlabObject +* CLI: Add the -g short option for --gitlab +* Provide a create method for GitlabObject's +* Rename the _created attribute _from_api +* More unit tests +* CLI: fix error when arguments are missing (python 3) +* Remove deprecated methods +* Implement managers to get access to resources +* Documentation improvements +* Add fork project support +* Deprecate the "old" Gitlab methods +* Add support for groups search + +Version 0.10_: - 2015-12-29 +--------------------------- + +* Implement pagination for list() (#63) +* Fix url when fetching a single MergeRequest +* Add support to update MergeRequestNotes +* API: Provide a Gitlab.from_config method +* setup.py: require requests>=1 (#69) +* Fix deletion of object not using 'id' as ID (#68) +* Fix GET/POST for project files +* Make 'confirm' an optional attribute for user creation +* Python 3 compatibility fixes +* Add support for group members update (#73) + +Version 0.9.2_: - 2015-07-11 +---------------------------- + +* CLI: fix the update and delete subcommands (#62) + +Version 0.9.1_: - 2015-05-15 +---------------------------- + +* Fix the setup.py script + +Version 0.9_: - 2015-05-15 +-------------------------- + +* Implement argparse libray for parsing argument on CLI +* Provide unit tests and (a few) functional tests +* Provide PEP8 tests +* Use tox to run the tests +* CLI: provide a --config-file option +* Turn the gitlab module into a proper package +* Allow projects to be updated +* Use more pythonic names for some methods +* Deprecate some Gitlab object methods: + - raw* methods should never have been exposed; replace them with _raw_* + methods + - setCredentials and setToken are replaced with set_credentials and + set_token +* Sphinx: don't hardcode the version in conf.py + +Version 0.8_: - 2014-10-26 +-------------------------- + +* Better python 2.6 and python 3 support +* Timeout support in HTTP requests +* Gitlab.get() raised GitlabListError instead of GitlabGetError +* Support api-objects which don't have id in api response +* Add ProjectLabel and ProjectFile classes +* Moved url attributes to separate list +* Added list for delete attributes + +Version 0.7_: - 2014-08-21 +-------------------------- + +* Fix license classifier in setup.py +* Fix encoding error when printing to redirected output +* Fix encoding error when updating with redirected output +* Add support for UserKey listing and deletion +* Add support for branches creation and deletion +* Support state_event in ProjectMilestone (#30) +* Support namespace/name for project id (#28) +* Fix handling of boolean values (#22) + +Version 0.6_: - 2014-01-16 +-------------------------- + +* IDs can be unicode (#15) +* ProjectMember: constructor should not create a User object +* Add support for extra parameters when listing all projects (#12) +* Projects listing: explicitly define arguments for pagination + +Version 0.5_: - 2013-12-26 +-------------------------- + +* Add SSH key for user +* Fix comments +* Add support for project events +* Support creation of projects for users +* Project: add methods for create/update/delete files +* Support projects listing: search, all, owned +* System hooks can't be updated +* Project.archive(): download tarball of the project +* Define new optional attributes for user creation +* Provide constants for access permissions in groups + +Version 0.4_: - 2013-09-26 +-------------------------- + +* Fix strings encoding (Closes #6) +* Allow to get a project commit (GitLab 6.1) +* ProjectMergeRequest: fix Note() method +* Gitlab 6.1 methods: diff, blob (commit), tree, blob (project) +* Add support for Gitlab 6.1 group members + +Version 0.3_: - 2013-08-27 +-------------------------- + +* Use PRIVATE-TOKEN header for passing the auth token +* provide a AUTHORS file +* cli: support ssl_verify config option +* Add ssl_verify option to Gitlab object. Defauls to True +* Correct url for merge requests API. + +Version 0.2_: - 2013-08-08 +-------------------------- + +* provide a pip requirements.txt +* drop some debug statements + +Version 0.1 - 2013-07-08 +------------------------ + +* Initial release + +.. _0.19: https://github.com/gpocentek/python-gitlab/compare/0.18...0.19 +.. _0.18: https://github.com/gpocentek/python-gitlab/compare/0.17...0.18 +.. _0.17: https://github.com/gpocentek/python-gitlab/compare/0.16...0.17 +.. _0.16: https://github.com/gpocentek/python-gitlab/compare/0.15.1...0.16 +.. _0.15.1: https://github.com/gpocentek/python-gitlab/compare/0.15...0.15.1 +.. _0.15: https://github.com/gpocentek/python-gitlab/compare/0.14...0.15 +.. _0.14: https://github.com/gpocentek/python-gitlab/compare/0.13...0.14 +.. _0.13: https://github.com/gpocentek/python-gitlab/compare/0.12.2...0.13 +.. _0.12.2: https://github.com/gpocentek/python-gitlab/compare/0.12.1...0.12.2 +.. _0.12.1: https://github.com/gpocentek/python-gitlab/compare/0.12...0.12.1 +.. _0.12: https://github.com/gpocentek/python-gitlab/compare/0.11.1...0.12 +.. _0.11.1: https://github.com/gpocentek/python-gitlab/compare/0.11...0.11.1 +.. _0.11: https://github.com/gpocentek/python-gitlab/compare/0.10...0.11 +.. _0.10: https://github.com/gpocentek/python-gitlab/compare/0.9.2...0.10 +.. _0.9.2: https://github.com/gpocentek/python-gitlab/compare/0.9.1...0.9.2 +.. _0.9.1: https://github.com/gpocentek/python-gitlab/compare/0.9...0.9.1 +.. _0.9: https://github.com/gpocentek/python-gitlab/compare/0.8...0.9 +.. _0.8: https://github.com/gpocentek/python-gitlab/compare/0.7...0.8 +.. _0.7: https://github.com/gpocentek/python-gitlab/compare/0.6...0.7 +.. _0.6: https://github.com/gpocentek/python-gitlab/compare/0.5...0.6 +.. _0.5: https://github.com/gpocentek/python-gitlab/compare/0.4...0.5 +.. _0.4: https://github.com/gpocentek/python-gitlab/compare/0.3...0.4 +.. _0.3: https://github.com/gpocentek/python-gitlab/compare/0.2...0.3 +.. _0.2: https://github.com/gpocentek/python-gitlab/compare/0.1...0.2 From 35339d667097d8b937c1f9f2407e4c109834ad54 Mon Sep 17 00:00:00 2001 From: Gauvain Pocentek Date: Fri, 17 Mar 2017 16:41:07 +0100 Subject: [PATCH 03/15] Make sure that manager objects are never overwritten Group.projects (manager) can be replaced by a list of Project objects when creating/updating objects. The GroupObject API is more consistent and closer to the GitLab API, so make sure it is always used. Fixes #209 --- RELEASE_NOTES.rst | 19 +++++++++++++++++++ gitlab/objects.py | 6 +++++- 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 RELEASE_NOTES.rst diff --git a/RELEASE_NOTES.rst b/RELEASE_NOTES.rst new file mode 100644 index 000000000..669e00ed3 --- /dev/null +++ b/RELEASE_NOTES.rst @@ -0,0 +1,19 @@ +############################### +Release notes for python-gitlab +############################### + +This page describes important changes between python-gitlab releases. + +Changes from 0.19 to 0.20 +========================= + +* The ``projects`` attribute of ``Group`` objects is not a list of ``Project`` + objects anymore. It is a Manager object giving access to ``GroupProject`` + objects. To get the list of projects use: + + .. code-block:: python + + group.projects.list() + + Documentation for ``Group`` objects: + http://python-gitlab.readthedocs.io/en/stable/gl_objects/groups.html#examples diff --git a/gitlab/objects.py b/gitlab/objects.py index efe75d0a6..3c38e8e4a 100644 --- a/gitlab/objects.py +++ b/gitlab/objects.py @@ -297,6 +297,11 @@ def _set_from_dict(self, data, **kwargs): return for k, v in data.items(): + # If a k attribute already exists and is a Manager, do nothing (see + # https://github.com/gpocentek/python-gitlab/issues/209) + if isinstance(getattr(self, k, None), BaseManager): + continue + if isinstance(v, list): self.__dict__[k] = [] for i in v: @@ -937,7 +942,6 @@ class GroupAccessRequestManager(BaseManager): class Group(GitlabObject): _url = '/groups' - _constructorTypes = {'projects': 'Project'} requiredCreateAttrs = ['name', 'path'] optionalCreateAttrs = ['description', 'visibility_level'] optionalUpdateAttrs = ['name', 'path', 'description', 'visibility_level'] From 99e6f65fb965aefc09ecba67f7155baf2c4379a6 Mon Sep 17 00:00:00 2001 From: Gauvain Pocentek Date: Fri, 17 Mar 2017 16:48:08 +0100 Subject: [PATCH 04/15] Minor changelog formatting update --- ChangeLog.rst | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/ChangeLog.rst b/ChangeLog.rst index 751023239..2e51dbfcc 100644 --- a/ChangeLog.rst +++ b/ChangeLog.rst @@ -1,7 +1,7 @@ python-gitlab Changelog ======================= -Version 0.19_: - 2017-02-21 +Version 0.19_ - 2017-02-21 --------------------------- * Update project.archive() docs @@ -17,7 +17,7 @@ Version 0.19_: - 2017-02-21 * Handle settings.domain_whitelist, partly * {Project,Group}Member: support expires_at attribute -Version 0.18_: - 2016-12-27 +Version 0.18_ - 2016-12-27 --------------------------- * Fix JIRA service editing for GitLab 8.14+ @@ -32,7 +32,7 @@ Version 0.18_: - 2016-12-27 * Update known attributes for projects * sudo: always use strings -Version 0.17_: - 2016-12-02 +Version 0.17_ - 2016-12-02 --------------------------- * README: add badges for pypi and RTD @@ -67,7 +67,7 @@ Version 0.17_: - 2016-12-02 * Rework requests arguments (support latest requests release) * Fix `should_remove_source_branch` -Version 0.16_: - 2016-10-16 +Version 0.16_ - 2016-10-16 --------------------------- * Add the ability to fork to a specific namespace @@ -84,14 +84,14 @@ Version 0.16_: - 2016-10-16 * Add ProjectBuild.erase() * Implement ProjectBuild.play() -Version 0.15.1_: - 2016-10-16 +Version 0.15.1_ - 2016-10-16 ----------------------------- * docs: improve the pagination section * Fix and test pagination * 'path' is an existing gitlab attr, don't use it as method argument -Version 0.15_: - 2016-08-28 +Version 0.15_ - 2016-08-28 --------------------------- * Add a basic HTTP debug method @@ -112,7 +112,7 @@ Version 0.15_: - 2016-08-28 * Add support for access requests * Add support for project deployments -Version 0.14_: - 2016-08-07 +Version 0.14_ - 2016-08-07 --------------------------- * Remove 'next_url' from kwargs before passing it to the cls constructor. @@ -164,7 +164,7 @@ Version 0.14_: - 2016-08-07 * MR (un)subscribe: don't fail if state doesn't change * MR merge(): update the object -Version 0.13_: - 2016-05-16 +Version 0.13_ - 2016-05-16 --------------------------- * Add support for MergeRequest validation @@ -191,7 +191,7 @@ Version 0.13_: - 2016-05-16 * Implement list/get licenses * Manage optional parameters for list() and get() -Version 0.12.2_: - 2016-03-19 +Version 0.12.2_ - 2016-03-19 ----------------------------- * Add new `ProjectHook` attributes @@ -211,12 +211,12 @@ Version 0.12.2_: - 2016-03-19 * Fix the 'invalid syntax' error on Python 3.2 * Gitlab.update(): use the proper attributes if defined -Version 0.12.1_: - 2016-02-03 +Version 0.12.1_ - 2016-02-03 ----------------------------- * Fix a broken upload to pypi -Version 0.12_: - 2016-02-03 +Version 0.12_ - 2016-02-03 --------------------------- * Improve documentation @@ -240,7 +240,7 @@ Version 0.12_: - 2016-02-03 * Fix Project.tree() * Add support for project builds -Version 0.11.1_: - 2016-01-17 +Version 0.11.1_ - 2016-01-17 ----------------------------- * Fix discovery of parents object attrs for managers @@ -248,7 +248,7 @@ Version 0.11.1_: - 2016-01-17 * Support deletion without getting the object first * Improve the documentation -Version 0.11_: - 2016-01-09 +Version 0.11_ - 2016-01-09 --------------------------- * functional_tests.sh: support python 2 and 3 @@ -265,7 +265,7 @@ Version 0.11_: - 2016-01-09 * Deprecate the "old" Gitlab methods * Add support for groups search -Version 0.10_: - 2015-12-29 +Version 0.10_ - 2015-12-29 --------------------------- * Implement pagination for list() (#63) @@ -279,17 +279,17 @@ Version 0.10_: - 2015-12-29 * Python 3 compatibility fixes * Add support for group members update (#73) -Version 0.9.2_: - 2015-07-11 +Version 0.9.2_ - 2015-07-11 ---------------------------- * CLI: fix the update and delete subcommands (#62) -Version 0.9.1_: - 2015-05-15 +Version 0.9.1_ - 2015-05-15 ---------------------------- * Fix the setup.py script -Version 0.9_: - 2015-05-15 +Version 0.9_ - 2015-05-15 -------------------------- * Implement argparse libray for parsing argument on CLI @@ -307,7 +307,7 @@ Version 0.9_: - 2015-05-15 set_token * Sphinx: don't hardcode the version in conf.py -Version 0.8_: - 2014-10-26 +Version 0.8_ - 2014-10-26 -------------------------- * Better python 2.6 and python 3 support @@ -318,7 +318,7 @@ Version 0.8_: - 2014-10-26 * Moved url attributes to separate list * Added list for delete attributes -Version 0.7_: - 2014-08-21 +Version 0.7_ - 2014-08-21 -------------------------- * Fix license classifier in setup.py @@ -330,7 +330,7 @@ Version 0.7_: - 2014-08-21 * Support namespace/name for project id (#28) * Fix handling of boolean values (#22) -Version 0.6_: - 2014-01-16 +Version 0.6_ - 2014-01-16 -------------------------- * IDs can be unicode (#15) @@ -338,7 +338,7 @@ Version 0.6_: - 2014-01-16 * Add support for extra parameters when listing all projects (#12) * Projects listing: explicitly define arguments for pagination -Version 0.5_: - 2013-12-26 +Version 0.5_ - 2013-12-26 -------------------------- * Add SSH key for user @@ -352,7 +352,7 @@ Version 0.5_: - 2013-12-26 * Define new optional attributes for user creation * Provide constants for access permissions in groups -Version 0.4_: - 2013-09-26 +Version 0.4_ - 2013-09-26 -------------------------- * Fix strings encoding (Closes #6) @@ -361,7 +361,7 @@ Version 0.4_: - 2013-09-26 * Gitlab 6.1 methods: diff, blob (commit), tree, blob (project) * Add support for Gitlab 6.1 group members -Version 0.3_: - 2013-08-27 +Version 0.3_ - 2013-08-27 -------------------------- * Use PRIVATE-TOKEN header for passing the auth token @@ -370,7 +370,7 @@ Version 0.3_: - 2013-08-27 * Add ssl_verify option to Gitlab object. Defauls to True * Correct url for merge requests API. -Version 0.2_: - 2013-08-08 +Version 0.2_ - 2013-08-08 -------------------------- * provide a pip requirements.txt From ea0759d71c6678b8ce65791535a9be1675d9cfab Mon Sep 17 00:00:00 2001 From: Gauvain Pocentek Date: Fri, 17 Mar 2017 17:00:33 +0100 Subject: [PATCH 05/15] Include chanlog and release notes in docs --- ChangeLog.rst | 4 ++-- RELEASE_NOTES.rst | 6 +++--- docs/api-objects.rst | 6 +++--- docs/api/modules.rst | 4 ++-- docs/changelog.rst | 1 + docs/index.rst | 2 ++ docs/release_notes.rst | 1 + 7 files changed, 14 insertions(+), 10 deletions(-) create mode 100644 docs/changelog.rst create mode 100644 docs/release_notes.rst diff --git a/ChangeLog.rst b/ChangeLog.rst index 2e51dbfcc..8e141d1de 100644 --- a/ChangeLog.rst +++ b/ChangeLog.rst @@ -1,5 +1,5 @@ -python-gitlab Changelog -======================= +ChangeLog +========= Version 0.19_ - 2017-02-21 --------------------------- diff --git a/RELEASE_NOTES.rst b/RELEASE_NOTES.rst index 669e00ed3..d107aaa23 100644 --- a/RELEASE_NOTES.rst +++ b/RELEASE_NOTES.rst @@ -1,6 +1,6 @@ -############################### -Release notes for python-gitlab -############################### +############# +Release notes +############# This page describes important changes between python-gitlab releases. diff --git a/docs/api-objects.rst b/docs/api-objects.rst index 010e9d650..78b964652 100644 --- a/docs/api-objects.rst +++ b/docs/api-objects.rst @@ -1,6 +1,6 @@ -######################## -API objects manipulation -######################## +############ +API examples +############ .. toctree:: :maxdepth: 1 diff --git a/docs/api/modules.rst b/docs/api/modules.rst index 7b09ae1b6..3ec5a68fe 100644 --- a/docs/api/modules.rst +++ b/docs/api/modules.rst @@ -1,5 +1,5 @@ -gitlab -====== +API documentation +================= .. toctree:: :maxdepth: 4 diff --git a/docs/changelog.rst b/docs/changelog.rst new file mode 100644 index 000000000..91bdab9e7 --- /dev/null +++ b/docs/changelog.rst @@ -0,0 +1 @@ +.. include:: ../ChangeLog.rst diff --git a/docs/index.rst b/docs/index.rst index 54472fe43..a1df804da 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -11,6 +11,8 @@ Contents: .. toctree:: :maxdepth: 2 + changelog + release_notes install cli api-usage diff --git a/docs/release_notes.rst b/docs/release_notes.rst new file mode 100644 index 000000000..db74610a0 --- /dev/null +++ b/docs/release_notes.rst @@ -0,0 +1 @@ +.. include:: ../RELEASE_NOTES.rst From a3f2ab138502cf3217d1b97ae7f3cd3a4f8b324f Mon Sep 17 00:00:00 2001 From: Gauvain Pocentek Date: Fri, 17 Mar 2017 17:39:20 +0100 Subject: [PATCH 06/15] Add DeployKey{,Manager} classes They are the same as Key and KeyManager but the name makes more sense. Fixes #212 --- RELEASE_NOTES.rst | 12 +++++++++++- docs/gl_objects/deploy_keys.py | 4 ++-- docs/gl_objects/deploy_keys.rst | 14 +++++++++----- gitlab/__init__.py | 1 + gitlab/objects.py | 17 +++++++++++++++++ 5 files changed, 40 insertions(+), 8 deletions(-) diff --git a/RELEASE_NOTES.rst b/RELEASE_NOTES.rst index d107aaa23..0b15c1166 100644 --- a/RELEASE_NOTES.rst +++ b/RELEASE_NOTES.rst @@ -15,5 +15,15 @@ Changes from 0.19 to 0.20 group.projects.list() - Documentation for ``Group`` objects: + Documentation: http://python-gitlab.readthedocs.io/en/stable/gl_objects/groups.html#examples + + Related issue: https://github.com/gpocentek/python-gitlab/issues/209 + +* The ``Key`` objects are deprecated in favor of the new ``DeployKey`` objects. + They are exactly the same but the name makes more sense. + + Documentation: + http://python-gitlab.readthedocs.io/en/stable/gl_objects/deploy_keys.html + + Related issue: https://github.com/gpocentek/python-gitlab/issues/212 diff --git a/docs/gl_objects/deploy_keys.py b/docs/gl_objects/deploy_keys.py index 5d85055a7..84da07934 100644 --- a/docs/gl_objects/deploy_keys.py +++ b/docs/gl_objects/deploy_keys.py @@ -1,9 +1,9 @@ # global list -keys = gl.keys.list() +keys = gl.deploykeys.list() # end global list # global get -key = gl.keys.get(key_id) +key = gl.deploykeys.get(key_id) # end global get # list diff --git a/docs/gl_objects/deploy_keys.rst b/docs/gl_objects/deploy_keys.rst index 57c129848..28033cb02 100644 --- a/docs/gl_objects/deploy_keys.rst +++ b/docs/gl_objects/deploy_keys.rst @@ -5,8 +5,10 @@ Deploy keys Deploy keys =========== -Use :class:`~gitlab.objects.Key` objects to manipulate deploy keys. The -:attr:`gitlab.Gitlab.keys` manager object provides helper functions. +Deploy keys allow read-only access to multiple projects with a single SSH key. + +* Object class: :class:`~gitlab.objects.DeployKey` +* Manager object: :attr:`gitlab.Gitlab.deploykeys` Examples -------- @@ -26,9 +28,11 @@ Get a single deploy key: Deploy keys for projects ======================== -Use :class:`~gitlab.objects.ProjectKey` objects to manipulate deploy keys for -projects. The :attr:`gitlab.Gitlab.project_keys` and :attr:`Project.keys -` manager objects provide helper functions. +Deploy keys can be managed on a per-project basis. + +* Object class: :class:`~gitlab.objects.ProjectKey` +* Manager objects: :attr:`gitlab.Gitlab.project_keys` and :attr:`Project.keys + ` Examples -------- diff --git a/gitlab/__init__.py b/gitlab/__init__.py index 119dab080..cce282dbb 100644 --- a/gitlab/__init__.py +++ b/gitlab/__init__.py @@ -91,6 +91,7 @@ def __init__(self, url, private_token=None, email=None, password=None, self.broadcastmessages = BroadcastMessageManager(self) self.keys = KeyManager(self) + self.deploykeys = DeployKeyManager(self) self.gitlabciymls = GitlabciymlManager(self) self.gitignores = GitignoreManager(self) self.groups = GroupManager(self) diff --git a/gitlab/objects.py b/gitlab/objects.py index 3c38e8e4a..f06765746 100644 --- a/gitlab/objects.py +++ b/gitlab/objects.py @@ -802,11 +802,28 @@ class Key(GitlabObject): canUpdate = False canDelete = False + def __init__(self, *args, **kwargs): + warnings.warn("`Key` is deprecated, use `DeployKey` instead", + DeprecationWarning) + super(Key, self).__init__(*args, **kwargs) + class KeyManager(BaseManager): obj_cls = Key +class DeployKey(GitlabObject): + _url = '/deploy_keys' + canGet = 'from_list' + canCreate = False + canUpdate = False + canDelete = False + + +class DeployKeyManager(BaseManager): + obj_cls = DeployKey + + class NotificationSettings(GitlabObject): _url = '/notification_settings' _id_in_update_url = False From e39d7eaaba18a7aa5cbcb4240feb0db11516b312 Mon Sep 17 00:00:00 2001 From: Gauvain Pocentek Date: Fri, 17 Mar 2017 17:56:52 +0100 Subject: [PATCH 07/15] Add support for merge request notes deletion Fixes #227 --- gitlab/objects.py | 1 - 1 file changed, 1 deletion(-) diff --git a/gitlab/objects.py b/gitlab/objects.py index f06765746..47907120e 100644 --- a/gitlab/objects.py +++ b/gitlab/objects.py @@ -1714,7 +1714,6 @@ class ProjectMergeRequestDiffManager(BaseManager): class ProjectMergeRequestNote(GitlabObject): _url = '/projects/%(project_id)s/merge_requests/%(merge_request_id)s/notes' _constructorTypes = {'author': 'User'} - canDelete = False requiredUrlAttrs = ['project_id', 'merge_request_id'] requiredCreateAttrs = ['body'] From 3b388447fecab4d86a3387178bfb2876776d7567 Mon Sep 17 00:00:00 2001 From: Gauvain Pocentek Date: Fri, 17 Mar 2017 18:14:19 +0100 Subject: [PATCH 08/15] Properly handle extra args when listing with all=True Fixes #233 --- gitlab/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/gitlab/__init__.py b/gitlab/__init__.py index cce282dbb..721106c51 100644 --- a/gitlab/__init__.py +++ b/gitlab/__init__.py @@ -337,6 +337,7 @@ def _raw_list(self, path_, cls, extra_attrs={}, **kwargs): if ('next' in r.links and 'url' in r.links['next'] and get_all_results is True): args = kwargs.copy() + args.update(extra_attrs) args['next_url'] = r.links['next']['url'] results.extend(self.list(cls, **args)) return results From 8c27e70b821e02921dfec4f8e4c6b77b5b284009 Mon Sep 17 00:00:00 2001 From: Mond WAN Date: Sat, 18 Mar 2017 16:48:11 +0800 Subject: [PATCH 09/15] Implement pipeline creation API (#237) --- docs/gl_objects/projects.py | 6 ++++++ docs/gl_objects/projects.rst | 6 ++++++ gitlab/objects.py | 6 +++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/docs/gl_objects/projects.py b/docs/gl_objects/projects.py index 54bde842e..4412f22f8 100644 --- a/docs/gl_objects/projects.py +++ b/docs/gl_objects/projects.py @@ -400,6 +400,12 @@ pipeline = project.pipelines.get(pipeline_id) # end pipeline get +# pipeline create +pipeline = gl.project_pipelines.create({'project_id': 1, 'ref': 'master'}) +# or +pipeline = project.pipelines.create({'ref': 'master'}) +# end pipeline create + # pipeline retry pipeline.retry() # end pipeline retry diff --git a/docs/gl_objects/projects.rst b/docs/gl_objects/projects.rst index dc6c48baf..300b84845 100644 --- a/docs/gl_objects/projects.rst +++ b/docs/gl_objects/projects.rst @@ -438,6 +438,12 @@ Cancel builds in a pipeline: :start-after: # pipeline cancel :end-before: # end pipeline cancel +Create a pipeline for a particular reference: + +.. literalinclude:: projects.py + :start-after: # pipeline create + :end-before: # end pipeline create + Services -------- diff --git a/gitlab/objects.py b/gitlab/objects.py index 47907120e..119671cc0 100644 --- a/gitlab/objects.py +++ b/gitlab/objects.py @@ -1991,10 +1991,14 @@ class ProjectFileManager(BaseManager): class ProjectPipeline(GitlabObject): _url = '/projects/%(project_id)s/pipelines' - canCreate = False + _create_url = '/projects/%(project_id)s/pipeline' + canUpdate = False canDelete = False + requiredUrlAttrs = ['project_id'] + requiredCreateAttrs = ['ref'] + def retry(self, **kwargs): """Retries failed builds in a pipeline. From 380bcc4cce66d7b2c080f258a1acb0d14a5a1fc3 Mon Sep 17 00:00:00 2001 From: Gauvain Pocentek Date: Sat, 18 Mar 2017 17:08:33 +0100 Subject: [PATCH 10/15] Make GroupProject inherit from Project Fixes #209 --- gitlab/objects.py | 147 +++++++++++++++++++++++----------------------- 1 file changed, 75 insertions(+), 72 deletions(-) diff --git a/gitlab/objects.py b/gitlab/objects.py index 47907120e..e83e6187d 100644 --- a/gitlab/objects.py +++ b/gitlab/objects.py @@ -915,20 +915,6 @@ class GroupNotificationSettingsManager(BaseManager): obj_cls = GroupNotificationSettings -class GroupProject(GitlabObject): - _url = '/groups/%(group_id)s/projects' - canGet = 'from_list' - canCreate = False - canDelete = False - canUpdate = False - optionalListAttrs = ['archived', 'visibility', 'order_by', 'sort', - 'search', 'ci_enabled_first'] - - -class GroupProjectManager(BaseManager): - obj_cls = GroupProject - - class GroupAccessRequest(GitlabObject): _url = '/groups/%(group_id)s/access_requests' canGet = 'from_list' @@ -957,64 +943,6 @@ class GroupAccessRequestManager(BaseManager): obj_cls = GroupAccessRequest -class Group(GitlabObject): - _url = '/groups' - requiredCreateAttrs = ['name', 'path'] - optionalCreateAttrs = ['description', 'visibility_level'] - optionalUpdateAttrs = ['name', 'path', 'description', 'visibility_level'] - shortPrintAttr = 'name' - managers = ( - ('accessrequests', GroupAccessRequestManager, [('group_id', 'id')]), - ('members', GroupMemberManager, [('group_id', 'id')]), - ('notificationsettings', GroupNotificationSettingsManager, - [('group_id', 'id')]), - ('projects', GroupProjectManager, [('group_id', 'id')]), - ('issues', GroupIssueManager, [('group_id', 'id')]), - ) - - GUEST_ACCESS = gitlab.GUEST_ACCESS - REPORTER_ACCESS = gitlab.REPORTER_ACCESS - DEVELOPER_ACCESS = gitlab.DEVELOPER_ACCESS - MASTER_ACCESS = gitlab.MASTER_ACCESS - OWNER_ACCESS = gitlab.OWNER_ACCESS - - VISIBILITY_PRIVATE = gitlab.VISIBILITY_PRIVATE - VISIBILITY_INTERNAL = gitlab.VISIBILITY_INTERNAL - VISIBILITY_PUBLIC = gitlab.VISIBILITY_PUBLIC - - def transfer_project(self, id, **kwargs): - """Transfers a project to this new groups. - - Attrs: - id (int): ID of the project to transfer. - - Raises: - GitlabConnectionError: If the server cannot be reached. - GitlabTransferProjectError: If the server fails to perform the - request. - """ - url = '/groups/%d/projects/%d' % (self.id, id) - r = self.gitlab._raw_post(url, None, **kwargs) - raise_error_from_response(r, GitlabTransferProjectError, 201) - - -class GroupManager(BaseManager): - obj_cls = Group - - def search(self, query, **kwargs): - """Searches groups by name. - - Args: - query (str): The search string - all (bool): If True, return all the items, without pagination - - Returns: - list(Group): a list of matching groups. - """ - url = '/groups?search=' + query - return self.gitlab._raw_list(url, self.obj_cls, **kwargs) - - class Hook(GitlabObject): _url = '/hooks' canUpdate = False @@ -2703,6 +2631,81 @@ def starred(self, **kwargs): return self.gitlab._raw_list("/projects/starred", Project, **kwargs) +class GroupProject(Project): + _url = '/groups/%(group_id)s/projects' + canGet = 'from_list' + canCreate = False + canDelete = False + canUpdate = False + optionalListAttrs = ['archived', 'visibility', 'order_by', 'sort', + 'search', 'ci_enabled_first'] + + def __init__(self, *args, **kwargs): + Project.__init__(self, *args, **kwargs) + + +class GroupProjectManager(BaseManager): + obj_cls = GroupProject + + +class Group(GitlabObject): + _url = '/groups' + requiredCreateAttrs = ['name', 'path'] + optionalCreateAttrs = ['description', 'visibility_level'] + optionalUpdateAttrs = ['name', 'path', 'description', 'visibility_level'] + shortPrintAttr = 'name' + managers = ( + ('accessrequests', GroupAccessRequestManager, [('group_id', 'id')]), + ('members', GroupMemberManager, [('group_id', 'id')]), + ('notificationsettings', GroupNotificationSettingsManager, + [('group_id', 'id')]), + ('projects', GroupProjectManager, [('group_id', 'id')]), + ('issues', GroupIssueManager, [('group_id', 'id')]), + ) + + GUEST_ACCESS = gitlab.GUEST_ACCESS + REPORTER_ACCESS = gitlab.REPORTER_ACCESS + DEVELOPER_ACCESS = gitlab.DEVELOPER_ACCESS + MASTER_ACCESS = gitlab.MASTER_ACCESS + OWNER_ACCESS = gitlab.OWNER_ACCESS + + VISIBILITY_PRIVATE = gitlab.VISIBILITY_PRIVATE + VISIBILITY_INTERNAL = gitlab.VISIBILITY_INTERNAL + VISIBILITY_PUBLIC = gitlab.VISIBILITY_PUBLIC + + def transfer_project(self, id, **kwargs): + """Transfers a project to this new groups. + + Attrs: + id (int): ID of the project to transfer. + + Raises: + GitlabConnectionError: If the server cannot be reached. + GitlabTransferProjectError: If the server fails to perform the + request. + """ + url = '/groups/%d/projects/%d' % (self.id, id) + r = self.gitlab._raw_post(url, None, **kwargs) + raise_error_from_response(r, GitlabTransferProjectError, 201) + + +class GroupManager(BaseManager): + obj_cls = Group + + def search(self, query, **kwargs): + """Searches groups by name. + + Args: + query (str): The search string + all (bool): If True, return all the items, without pagination + + Returns: + list(Group): a list of matching groups. + """ + url = '/groups?search=' + query + return self.gitlab._raw_list(url, self.obj_cls, **kwargs) + + class TeamMemberManager(BaseManager): obj_cls = TeamMember From 889bbe57d07966f1f146245db1e62accd5b23d93 Mon Sep 17 00:00:00 2001 From: Dmytro Litvinov Date: Mon, 20 Mar 2017 13:09:54 +0200 Subject: [PATCH 11/15] Change to correct logic of functions --- gitlab/objects.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gitlab/objects.py b/gitlab/objects.py index 119671cc0..99cf923e4 100644 --- a/gitlab/objects.py +++ b/gitlab/objects.py @@ -1588,7 +1588,7 @@ def add_spent_time(self, **kwargs): GitlabConnectionError: If the server cannot be reached. """ url = ('/projects/%(project_id)s/issues/%(issue_id)s/' - 'reset_spent_time' % + 'add_spent_time' % {'project_id': self.project_id, 'issue_id': self.id}) r = self.gitlab._raw_post(url, **kwargs) raise_error_from_response(r, GitlabTimeTrackingError, 200) @@ -1601,7 +1601,7 @@ def reset_spent_time(self, **kwargs): GitlabConnectionError: If the server cannot be reached. """ url = ('/projects/%(project_id)s/issues/%(issue_id)s/' - 'add_spent_time' % + 'reset_spent_time' % {'project_id': self.project_id, 'issue_id': self.id}) r = self.gitlab._raw_post(url, **kwargs) raise_error_from_response(r, GitlabTimeTrackingError, 200) From 8677f1c0250e9ab6b1e16da17d593101128cf057 Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 20 Mar 2017 13:15:11 +0100 Subject: [PATCH 12/15] add 'delete source branch' option when creating MR (#241) --- gitlab/objects.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitlab/objects.py b/gitlab/objects.py index 99cf923e4..7c961b380 100644 --- a/gitlab/objects.py +++ b/gitlab/objects.py @@ -1728,7 +1728,7 @@ class ProjectMergeRequest(GitlabObject): requiredUrlAttrs = ['project_id'] requiredCreateAttrs = ['source_branch', 'target_branch', 'title'] optionalCreateAttrs = ['assignee_id', 'description', 'target_project_id', - 'labels', 'milestone_id'] + 'labels', 'milestone_id', 'remove_source_branch'] optionalUpdateAttrs = ['target_branch', 'assignee_id', 'title', 'description', 'state_event', 'labels', 'milestone_id'] From 22bf12827387cb1719bacae6c0c745cd768eee6c Mon Sep 17 00:00:00 2001 From: Christian Date: Tue, 21 Mar 2017 06:50:20 +0100 Subject: [PATCH 13/15] Provide API wrapper for cherry picking commits (#236) --- docs/gl_objects/commits.py | 4 ++++ docs/gl_objects/commits.rst | 6 ++++++ gitlab/cli.py | 11 ++++++++++- gitlab/exceptions.py | 4 ++++ gitlab/objects.py | 21 +++++++++++++++++++-- 5 files changed, 43 insertions(+), 3 deletions(-) diff --git a/docs/gl_objects/commits.py b/docs/gl_objects/commits.py index 2ed66f560..0d47edb9b 100644 --- a/docs/gl_objects/commits.py +++ b/docs/gl_objects/commits.py @@ -39,6 +39,10 @@ diff = commit.diff() # end diff +# cherry +commit.cherry_pick(branch='target_branch') +# end cherry + # comments list comments = gl.project_commit_comments.list(project_id=1, commit_id='master') # or diff --git a/docs/gl_objects/commits.rst b/docs/gl_objects/commits.rst index 8be1b8602..6fef8bf7e 100644 --- a/docs/gl_objects/commits.rst +++ b/docs/gl_objects/commits.rst @@ -43,6 +43,12 @@ Get the diff for a commit: :start-after: # diff :end-before: # end diff +Cherry-pick a commit into another branch: + +.. literalinclude:: commits.py + :start-after: # cherry + :end-before: # end cherry + Commit comments =============== diff --git a/gitlab/cli.py b/gitlab/cli.py index 32b3ec850..2a419072a 100644 --- a/gitlab/cli.py +++ b/gitlab/cli.py @@ -42,7 +42,9 @@ gitlab.ProjectCommit: {'diff': {'required': ['id', 'project-id']}, 'blob': {'required': ['id', 'project-id', 'filepath']}, - 'builds': {'required': ['id', 'project-id']}}, + 'builds': {'required': ['id', 'project-id']}, + 'cherrypick': {'required': ['id', 'project-id', + 'branch']}}, gitlab.ProjectIssue: {'subscribe': {'required': ['id', 'project-id']}, 'unsubscribe': {'required': ['id', 'project-id']}, 'move': {'required': ['id', 'project-id', @@ -267,6 +269,13 @@ def do_project_commit_builds(self, cls, gl, what, args): except Exception as e: _die("Impossible to get commit builds", e) + def do_project_commit_cherrypick(self, cls, gl, what, args): + try: + o = self.do_get(cls, gl, what, args) + o.cherry_pick(branch=args['branch']) + except Exception as e: + _die("Impossible to cherry-pick commit", e) + def do_project_build_cancel(self, cls, gl, what, args): try: o = self.do_get(cls, gl, what, args) diff --git a/gitlab/exceptions.py b/gitlab/exceptions.py index 11bbe26cb..fc901d1a9 100644 --- a/gitlab/exceptions.py +++ b/gitlab/exceptions.py @@ -147,6 +147,10 @@ class GitlabTimeTrackingError(GitlabOperationError): pass +class GitlabCherryPickError(GitlabOperationError): + pass + + def raise_error_from_response(response, error, expected_code=200): """Tries to parse gitlab error message from response and raises error. diff --git a/gitlab/objects.py b/gitlab/objects.py index 7c961b380..245b88f79 100644 --- a/gitlab/objects.py +++ b/gitlab/objects.py @@ -1158,7 +1158,7 @@ class ProjectBranch(GitlabObject): requiredCreateAttrs = ['branch_name', 'ref'] def protect(self, protect=True, **kwargs): - """Protects the project.""" + """Protects the branch.""" url = self._url % {'project_id': self.project_id} action = 'protect' if protect else 'unprotect' url = "%s/%s/%s" % (url, self.name, action) @@ -1171,7 +1171,7 @@ def protect(self, protect=True, **kwargs): del self.protected def unprotect(self, **kwargs): - """Unprotects the project.""" + """Unprotects the branch.""" self.protect(False, **kwargs) @@ -1374,6 +1374,23 @@ def builds(self, **kwargs): {'project_id': self.project_id}, **kwargs) + def cherry_pick(self, branch, **kwargs): + """Cherry-pick a commit into a branch. + + Args: + branch (str): Name of target branch. + + Raises: + GitlabCherryPickError: If the cherry pick could not be applied. + """ + url = ('/projects/%s/repository/commits/%s/cherry_pick' % + (self.project_id, self.id)) + + r = self.gitlab._raw_post(url, data={'project_id': self.project_id, + 'branch': branch}, **kwargs) + errors = {400: GitlabCherryPickError} + raise_error_from_response(r, errors, expected_code=201) + class ProjectCommitManager(BaseManager): obj_cls = ProjectCommit From 989f3b706d97045f4ea6af69fd11233e2f54adbf Mon Sep 17 00:00:00 2001 From: Johan Brandhorst Date: Thu, 23 Mar 2017 18:47:03 +0000 Subject: [PATCH 14/15] Stop listing if recursion limit is hit (#234) --- docs/api-usage.rst | 4 ++- gitlab/__init__.py | 30 ++++++++++------ gitlab/tests/test_gitlab.py | 70 +++++++++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 11 deletions(-) diff --git a/docs/api-usage.rst b/docs/api-usage.rst index a15aecbfa..7b7ab7832 100644 --- a/docs/api-usage.rst +++ b/docs/api-usage.rst @@ -142,7 +142,9 @@ parameter to get all the items when using listing methods: python-gitlab will iterate over the list by calling the correspnding API multiple times. This might take some time if you have a lot of items to retrieve. This might also consume a lot of memory as all the items will be - stored in RAM. + stored in RAM. If you're encountering the python recursion limit exception, + use ``safe_all=True`` instead to stop pagination automatically if the + recursion limit is hit. Sudo ==== diff --git a/gitlab/__init__.py b/gitlab/__init__.py index 721106c51..421b9eb2c 100644 --- a/gitlab/__init__.py +++ b/gitlab/__init__.py @@ -112,8 +112,8 @@ def __init__(self, url, private_token=None, email=None, password=None, # build the "submanagers" for parent_cls in six.itervalues(globals()): if (not inspect.isclass(parent_cls) - or not issubclass(parent_cls, GitlabObject) - or parent_cls == CurrentUser): + or not issubclass(parent_cls, GitlabObject) + or parent_cls == CurrentUser): continue if not parent_cls.managers: @@ -312,11 +312,13 @@ def _raw_list(self, path_, cls, extra_attrs={}, **kwargs): params = extra_attrs.copy() params.update(kwargs.copy()) - get_all_results = kwargs.get('all', False) + catch_recursion_limit = kwargs.get('safe_all', False) + get_all_results = (kwargs.get('all', False) is True + or catch_recursion_limit) # Remove these keys to avoid breaking the listing (urls will get too # long otherwise) - for key in ['all', 'next_url']: + for key in ['all', 'next_url', 'safe_all']: if key in params: del params[key] @@ -334,12 +336,20 @@ def _raw_list(self, path_, cls, extra_attrs={}, **kwargs): results = [cls(self, item, **params) for item in r.json() if item is not None] - if ('next' in r.links and 'url' in r.links['next'] - and get_all_results is True): - args = kwargs.copy() - args.update(extra_attrs) - args['next_url'] = r.links['next']['url'] - results.extend(self.list(cls, **args)) + try: + if ('next' in r.links and 'url' in r.links['next'] + and get_all_results): + args = kwargs.copy() + args.update(extra_attrs) + args['next_url'] = r.links['next']['url'] + results.extend(self.list(cls, **args)) + except Exception as e: + # Catch the recursion limit exception if the 'safe_all' + # kwarg was provided + if not (catch_recursion_limit and + "maximum recursion depth exceeded" in str(e)): + raise e + return results def _raw_post(self, path_, data=None, content_type=None, **kwargs): diff --git a/gitlab/tests/test_gitlab.py b/gitlab/tests/test_gitlab.py index 4adf07f5a..4670def2f 100644 --- a/gitlab/tests/test_gitlab.py +++ b/gitlab/tests/test_gitlab.py @@ -26,6 +26,7 @@ from httmock import HTTMock # noqa from httmock import response # noqa from httmock import urlmatch # noqa +import six import gitlab from gitlab import * # noqa @@ -243,6 +244,75 @@ def resp_two(url, request): self.assertEqual(data[0].ref, "b") self.assertEqual(len(data), 2) + def test_list_recursion_limit_caught(self): + @urlmatch(scheme="http", netloc="localhost", + path='/api/v3/projects/1/repository/branches', method="get") + def resp_one(url, request): + """First request: + + http://localhost/api/v3/projects/1/repository/branches?per_page=1 + """ + headers = { + 'content-type': 'application/json', + 'link': '; rel="next", ; rel="las' + 't", ; rel="first"' + } + content = ('[{"branch_name": "otherbranch", ' + '"project_id": 1, "ref": "b"}]').encode("utf-8") + resp = response(200, content, headers, None, 5, request) + return resp + + @urlmatch(scheme="http", netloc="localhost", + path='/api/v3/projects/1/repository/branches', method="get", + query=r'.*page=2.*') + def resp_two(url, request): + # Mock a runtime error + raise RuntimeError("maximum recursion depth exceeded") + + with HTTMock(resp_two, resp_one): + data = self.gl.list(ProjectBranch, project_id=1, per_page=1, + safe_all=True) + self.assertEqual(data[0].branch_name, "otherbranch") + self.assertEqual(data[0].project_id, 1) + self.assertEqual(data[0].ref, "b") + self.assertEqual(len(data), 1) + + def test_list_recursion_limit_not_caught(self): + @urlmatch(scheme="http", netloc="localhost", + path='/api/v3/projects/1/repository/branches', method="get") + def resp_one(url, request): + """First request: + + http://localhost/api/v3/projects/1/repository/branches?per_page=1 + """ + headers = { + 'content-type': 'application/json', + 'link': '; rel="next", ; rel="las' + 't", ; rel="first"' + } + content = ('[{"branch_name": "otherbranch", ' + '"project_id": 1, "ref": "b"}]').encode("utf-8") + resp = response(200, content, headers, None, 5, request) + return resp + + @urlmatch(scheme="http", netloc="localhost", + path='/api/v3/projects/1/repository/branches', method="get", + query=r'.*page=2.*') + def resp_two(url, request): + # Mock a runtime error + raise RuntimeError("maximum recursion depth exceeded") + + with HTTMock(resp_two, resp_one): + with six.assertRaisesRegex(self, GitlabError, + "(maximum recursion depth exceeded)"): + self.gl.list(ProjectBranch, project_id=1, per_page=1, all=True) + def test_list_401(self): @urlmatch(scheme="http", netloc="localhost", path="/api/v3/projects/1/repository/branches", method="get") From c545504da79bca1f26ccfc16c3bf34ef3cc0d22c Mon Sep 17 00:00:00 2001 From: Gauvain Pocentek Date: Sat, 25 Mar 2017 16:39:48 +0100 Subject: [PATCH 15/15] Prepare 0.20 release --- AUTHORS | 5 +++++ ChangeLog.rst | 17 +++++++++++++++++ gitlab/__init__.py | 2 +- 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index d01d5783e..c5aafbf2d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -8,6 +8,7 @@ Contributors ------------ Adam Reid +Alexander Skiba Alex Widener Amar Sood (tekacs) Andjelko Horvat @@ -23,6 +24,7 @@ Crestez Dan Leonard Daniel Kimsey derek-austin Diego Giovane Pasqualin +Dmytro Litvinov Erik Weatherwax fgouteroux Greg Allen @@ -33,6 +35,7 @@ Ivica Arsov James (d0c_s4vage) Johnson James Johnson Jason Antman +Johan Brandhorst Jonathon Reinhart Koen Smets Kris Gambirazzi @@ -42,6 +45,7 @@ Matt Odden Michal Galet Mikhail Lopotkov Missionrulz +Mond WAN pa4373 Patrick Miller Peng Xiao @@ -51,6 +55,7 @@ Philipp Busch Rafael Eyng Richard Hansen samcday +savenger Stefan K. Dunkler Stefan Klug Stefano Mandruzzato diff --git a/ChangeLog.rst b/ChangeLog.rst index 8e141d1de..00663e7b8 100644 --- a/ChangeLog.rst +++ b/ChangeLog.rst @@ -1,6 +1,22 @@ ChangeLog ========= +Version 0.20_ - 2017-03-25 +--------------------------- + +* Add time tracking support (#222) +* Improve changelog (#229, #230) +* Make sure that manager objects are never overwritten (#209) +* Include chanlog and release notes in docs +* Add DeployKey{,Manager} classes (#212) +* Add support for merge request notes deletion (#227) +* Properly handle extra args when listing with all=True (#233) +* Implement pipeline creation API (#237) +* Fix spent_time methods +* Add 'delete source branch' option when creating MR (#241) +* Provide API wrapper for cherry picking commits (#236) +* Stop listing if recursion limit is hit (#234) + Version 0.19_ - 2017-02-21 --------------------------- @@ -381,6 +397,7 @@ Version 0.1 - 2013-07-08 * Initial release +.. _0.20: https://github.com/gpocentek/python-gitlab/compare/0.19...0.20 .. _0.19: https://github.com/gpocentek/python-gitlab/compare/0.18...0.19 .. _0.18: https://github.com/gpocentek/python-gitlab/compare/0.17...0.18 .. _0.17: https://github.com/gpocentek/python-gitlab/compare/0.16...0.17 diff --git a/gitlab/__init__.py b/gitlab/__init__.py index 421b9eb2c..1db03b0ac 100644 --- a/gitlab/__init__.py +++ b/gitlab/__init__.py @@ -34,7 +34,7 @@ from gitlab.objects import * # noqa __title__ = 'python-gitlab' -__version__ = '0.19' +__version__ = '0.20' __author__ = 'Gauvain Pocentek' __email__ = 'gauvain@pocentek.net' __license__ = 'LGPL3'