summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab-ci.yml96
-rw-r--r--.travis.yml21
-rw-r--r--docs/api-objects.rst2
-rw-r--r--docs/gl_objects/projects.rst33
-rw-r--r--docs/gl_objects/repositories.rst28
-rw-r--r--docs/gl_objects/repository_tags.rst47
-rw-r--r--gitlab/__init__.py2
-rw-r--r--gitlab/v4/objects.py57
-rw-r--r--tools/Dockerfile-test34
9 files changed, 298 insertions, 22 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..0b8fa4f
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,96 @@
+image: python:3.7
+
+stages:
+ - lint
+ - build-test-image
+ - test
+ - deploy
+
+commitlint:
+ image: node:12
+ stage: lint
+ before_script:
+ - npm install -g @commitlint/cli @commitlint/config-conventional
+ - 'echo "module.exports = {extends: [\"@commitlint/config-conventional\"]}" > commitlint.config.js'
+ script:
+ - npx commitlint --from=origin/master
+ except:
+ - master
+
+#build_test_image: # Currently hangs forever, because of GitLab Runner infrastructure issues
+# stage: build-test-image
+# image:
+# name: gcr.io/kaniko-project/executor:debug
+# entrypoint: [""]
+# script:
+# - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
+# - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/tools/Dockerfile-test --destination $CI_REGISTRY_IMAGE:test
+# only:
+# refs:
+# - master
+# changes:
+# - tools/
+
+.tox_includes: &tox_includes
+ stage: test
+ before_script:
+ - pip install tox
+ script:
+ - tox -e $TOX_ENV
+
+test_2.7:
+ <<: *tox_includes
+ image: python:2.7
+ variables:
+ TOX_ENV: py27
+
+test_3.4:
+ <<: *tox_includes
+ image: python:3.4
+ variables:
+ TOX_ENV: py34
+
+test_3.5:
+ <<: *tox_includes
+ image: python:3.5
+ variables:
+ TOX_ENV: py35
+
+test_3.6:
+ <<: *tox_includes
+ image: python:3.6
+ variables:
+ TOX_ENV: py36
+
+test_3.7:
+ <<: *tox_includes
+ image: python:3.7
+ variables:
+ TOX_ENV: py37
+
+test_3.8:
+ <<: *tox_includes
+ image: python:3.8-rc-alpine
+ variables:
+ TOX_ENV: py38
+ allow_failure: true
+
+test_docs:
+ <<: *tox_includes
+ variables:
+ TOX_ENV: docs
+
+deploy:
+ stage: deploy
+ script:
+ - pip install -U setuptools wheel twine
+ - python setup.py sdist bdist_wheel
+ # test package
+ - python3 -m venv test
+ - . test/bin/activate
+ - pip install -U dist/python-gitlab*.whl
+ - gitlab -h
+ - deactivate
+ - twine upload --skip-existing -u $TWINE_USERNAME -p $TWINE_PASSWORD dist/*
+ only:
+ - tags
diff --git a/.travis.yml b/.travis.yml
index e96e86f..1e9cc4d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,33 +1,12 @@
sudo: required
services:
- docker
-addons:
- apt:
- sources:
- - deadsnakes
- packages:
- - python3.5
language: python
python: 2.7
env:
- - TOX_ENV=py35
- - TOX_ENV=py34
- - TOX_ENV=py27
- - TOX_ENV=pep8
- - TOX_ENV=docs
- TOX_ENV=py_func_v4
- TOX_ENV=cli_func_v4
install:
- pip install tox
script:
- tox -e $TOX_ENV
-
-deploy:
- provider: pypi
- user: max-wittig
- password:
- secure: LmNkZdbNe1oBSJ/PeTCKXaeu9Ml/biY4ZN4aedbD4lLXbxV/sgsHEE4N1Xrg2D/CJsnNjBY7CHzO0vL5iak8IRpV61xkdquZHvAUQKuhjMY30HopReAEw8sP+Wpf3lYcD1BjC5KT9vqWG99feoQ6epRt//Xm4DdkBYNmmUsCsMBTZLlGnj3B/mE8w+XQxQpdA2QzpRJ549N12vidwZRKqP0Zuug3rELVSo64O2bpqarKx/EeUUhTXZ0Y4XeVYgvuHBjvPqtuSJzR17CNkjaBhacD7EFTP34sAaCKGRDpfYiiiGx9LeKOEAv5Hj0+LOqEC/o6EyiIFviE+HvLQ/kBLJ6Oo2p47fibyIU/YOAFdZYKmBRq2ZUaV0DhhuuCRPZ+yLrsuaFRrKTVEMsHVtdsXJkW5gKG08vwOndW+kamppRhkAcdFVyokIgu/6nPBRWMuS6ue2aKoKRdP2gmqk0daKM1ao2uv06A2/J1/xkPy1EX5MjyK8Mh78ooKjITp5DHYn8l1pxaB0YcEkRzfwMyLErGQaRDgo7rCOm0tTRNhArkn0VE1/KLKFbATo2NSxZDwUJQ5TBNCEqfdBN1VzNEduJ7ajbZpq3DsBRM/9hzQ5LLxn7azMl9m+WmT12Qcgz25wg2Sgbs9Z2rT6fto5h8GSLpy8ReHo+S6fALJBzA4pg=
- distributions: sdist bdist_wheel
- on:
- tags: true
- skip_existing: true
diff --git a/docs/api-objects.rst b/docs/api-objects.rst
index 0cc5014..451e411 100644
--- a/docs/api-objects.rst
+++ b/docs/api-objects.rst
@@ -34,6 +34,8 @@ API examples
gl_objects/pagesdomains
gl_objects/projects
gl_objects/runners
+ gl_objects/repositories
+ gl_objects/repository_tags
gl_objects/search
gl_objects/settings
gl_objects/snippets
diff --git a/docs/gl_objects/projects.rst b/docs/gl_objects/projects.rst
index b91f5f2..c151889 100644
--- a/docs/gl_objects/projects.rst
+++ b/docs/gl_objects/projects.rst
@@ -663,6 +663,39 @@ Delete project push rules::
pr.delete()
+Project releases
+================
+
+Reference
+---------
+
+* v4 API:
+
+ + :class:`gitlab.v4.objects.ProjectRelease`
+ + :class:`gitlab.v4.objects.ProjectReleaseManager`
+ + :attr:`gitlab.v4.objects.Project.releases`
+
+* Gitlab API: https://docs.gitlab.com/ee/api/releases/index.html
+
+Examples
+--------
+
+Get a list of releases from a project::
+
+ release = project.releases.list()
+
+Get a single release::
+
+ release = project.releases.get('v1.2.3')
+
+Create a release for a project tag::
+
+ release = project.releases.create({'name':'Demo Release', 'tag_name':'v1.2.3', 'description':'release notes go here'})
+
+Delete a release::
+
+ release = p.releases.delete('v1.2.3')
+
Project protected tags
======================
diff --git a/docs/gl_objects/repositories.rst b/docs/gl_objects/repositories.rst
new file mode 100644
index 0000000..6622c0c
--- /dev/null
+++ b/docs/gl_objects/repositories.rst
@@ -0,0 +1,28 @@
+#####################
+Registry Repositories
+#####################
+
+References
+----------
+
+* v4 API:
+
+ + :class:`gitlab.v4.objects.ProjectRegistryRepository`
+ + :class:`gitlab.v4.objects.ProjectRegistryRepositoryManager`
+ + :attr:`gitlab.v4.objects.Project.repositories`
+
+* Gitlab API: https://docs.gitlab.com/ce/api/container_registry.html
+
+Examples
+--------
+
+Get the list of container registry repositories associated with the project::
+
+ repositories = project.repositories.list()
+
+Delete repository::
+
+ project.repositories.delete(id=x)
+ # or
+ repository = repositories.pop()
+ repository.delete()
diff --git a/docs/gl_objects/repository_tags.rst b/docs/gl_objects/repository_tags.rst
new file mode 100644
index 0000000..94593da
--- /dev/null
+++ b/docs/gl_objects/repository_tags.rst
@@ -0,0 +1,47 @@
+########################
+Registry Repository Tags
+########################
+
+References
+----------
+
+* v4 API:
+
+ + :class:`gitlab.v4.objects.ProjectRegistryTag`
+ + :class:`gitlab.v4.objects.ProjectRegistryTagManager`
+ + :attr:`gitlab.v4.objects.Repository.tags`
+
+* Gitlab API: https://docs.gitlab.com/ce/api/container_registry.html
+
+Examples
+--------
+
+Get the list of repository tags in given registry::
+
+ repositories = project.repositories.list()
+ repository = repositories.pop()
+ tags = repository.tags.list()
+
+Get specific tag::
+
+ repository.tags.get(id=tag_name)
+
+Delete tag::
+
+ repository.tags.delete(id=tag_name)
+ # or
+ tag = repository.tags.get(id=tag_name)
+ tag.delete()
+
+Delete tag in bulk::
+
+ repository.tags.delete_in_bulk(keep_n=1)
+ # or
+ repository.tags.delete_in_bulk(older_than="1m")
+ # or
+ repository.tags.delete_in_bulk(name_regex="v.+", keep_n=2)
+
+.. note::
+
+ Delete in bulk is asnychronous operation and may take a while.
+ Refer to: https://docs.gitlab.com/ce/api/container_registry.html#delete-repository-tags-in-bulk
diff --git a/gitlab/__init__.py b/gitlab/__init__.py
index 819096d..9532267 100644
--- a/gitlab/__init__.py
+++ b/gitlab/__init__.py
@@ -359,7 +359,7 @@ class Gitlab(object):
def enable_debug(self):
import logging
try:
- from http.client import HTTPConnection
+ from http.client import HTTPConnection # noqa
except ImportError:
from httplib import HTTPConnection # noqa
diff --git a/gitlab/v4/objects.py b/gitlab/v4/objects.py
index 2175e0c..ed559cf 100644
--- a/gitlab/v4/objects.py
+++ b/gitlab/v4/objects.py
@@ -1177,6 +1177,49 @@ class PagesDomainManager(ListMixin, RESTManager):
_obj_cls = PagesDomain
+class ProjectRegistryRepository(ObjectDeleteMixin, RESTObject):
+ _managers = (
+ ('tags', 'ProjectRegistryTagManager'),
+ )
+
+
+class ProjectRegistryRepositoryManager(DeleteMixin, ListMixin, RESTManager):
+ _path = '/projects/%(project_id)s/registry/repositories'
+ _obj_cls = ProjectRegistryRepository
+ _from_parent_attrs = {'project_id': 'id'}
+
+
+class ProjectRegistryTag(ObjectDeleteMixin, RESTObject):
+ _id_attr = 'name'
+
+
+class ProjectRegistryTagManager(DeleteMixin, RetrieveMixin, RESTManager):
+ _obj_cls = ProjectRegistryTag
+ _from_parent_attrs = {'project_id': 'project_id', 'repository_id': 'id'}
+ _path = '/projects/%(project_id)s/registry/repositories/%(repository_id)s/tags'
+
+ @cli.register_custom_action('ProjectRegistryTagManager', optional=('name_regex', 'keep_n', 'older_than'))
+ @exc.on_http_error(exc.GitlabDeleteError)
+ def delete_in_bulk(self, name_regex='.*', **kwargs):
+ """Delete Tag in bulk
+
+ Args:
+ name_regex (string): The regex of the name to delete. To delete all
+ tags specify .*.
+ keep_n (integer): The amount of latest tags of given name to keep.
+ older_than (string): Tags to delete that are older than the given time,
+ written in human readable form 1h, 1d, 1month.
+ **kwargs: Extra options to send to the server (e.g. sudo)
+ Raises:
+ GitlabAuthenticationError: If authentication is not correct
+ GitlabDeleteError: If the server cannot perform the request
+ """
+ valid_attrs = ['keep_n', 'older_than']
+ data = {'name_regex': name_regex}
+ data.update({k: v for k, v in kwargs.items() if k in valid_attrs})
+ self.gitlab.http_delete(self.path, query_data=data, **kwargs)
+
+
class ProjectBoardList(SaveMixin, ObjectDeleteMixin, RESTObject):
pass
@@ -1993,6 +2036,18 @@ class ProjectPagesDomainManager(CRUDMixin, RESTManager):
_update_attrs = (tuple(), ('certificate', 'key'))
+class ProjectRelease(RESTObject):
+ _id_attr = 'tag_name'
+
+
+class ProjectReleaseManager(NoUpdateMixin, RESTManager):
+ _path = '/projects/%(project_id)s/releases'
+ _obj_cls = ProjectRelease
+ _from_parent_attrs = {'project_id': 'id'}
+ _create_attrs = (('name', 'tag_name', 'description', ),
+ ('ref', 'assets', ))
+
+
class ProjectTag(ObjectDeleteMixin, RESTObject):
_id_attr = 'name'
_short_print_attr = 'name'
@@ -3273,6 +3328,8 @@ class Project(SaveMixin, ObjectDeleteMixin, RESTObject):
('protectedtags', 'ProjectProtectedTagManager'),
('pipelineschedules', 'ProjectPipelineScheduleManager'),
('pushrules', 'ProjectPushRulesManager'),
+ ('releases', 'ProjectReleaseManager'),
+ ('repositories', 'ProjectRegistryRepositoryManager'),
('runners', 'ProjectRunnerManager'),
('services', 'ProjectServiceManager'),
('snippets', 'ProjectSnippetManager'),
diff --git a/tools/Dockerfile-test b/tools/Dockerfile-test
new file mode 100644
index 0000000..7d491de
--- /dev/null
+++ b/tools/Dockerfile-test
@@ -0,0 +1,34 @@
+FROM ubuntu:16.04
+# based on Vincent Robert <vincent.robert@genezys.net> initial Dockerfile
+MAINTAINER Gauvain Pocentek <gauvain@pocentek.net>
+
+# Install required packages
+RUN apt-get update \
+ && apt-get install -qy --no-install-recommends \
+ openssh-server \
+ ca-certificates \
+ curl \
+ tzdata \
+ && curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | bash \
+ && apt-get install -qy --no-install-recommends \
+ gitlab-ce=11.10.0-ce.0
+
+# Manage SSHD through runit
+RUN mkdir -p /opt/gitlab/sv/sshd/supervise \
+ && mkfifo /opt/gitlab/sv/sshd/supervise/ok \
+ && printf "#!/bin/sh\nexec 2>&1\numask 077\nexec /usr/sbin/sshd -D" > /opt/gitlab/sv/sshd/run \
+ && chmod a+x /opt/gitlab/sv/sshd/run \
+ && ln -s /opt/gitlab/sv/sshd /opt/gitlab/service \
+ && mkdir -p /var/run/sshd
+
+# Default root password
+RUN echo "gitlab_rails['initial_root_password'] = '5iveL!fe'" >> /etc/gitlab/gitlab.rb; \
+ sed -i "s,^external_url.*,external_url 'http://gitlab.test'," /etc/gitlab/gitlab.rb; \
+ echo 'pages_external_url "http://pages.gitlab.lxd/"' >> /etc/gitlab/gitlab.rb; \
+ echo "gitlab_pages['enable'] = true" >> /etc/gitlab/gitlab.rb
+
+# Expose web & ssh
+EXPOSE 80 22
+
+# Default is to run runit & reconfigure
+CMD sleep 3 && gitlab-ctl reconfigure & /opt/gitlab/embedded/bin/runsvdir-start