Skip to content

Commit b1ec2cc

Browse files
committed
Add CI for GitLab
1 parent db11e50 commit b1ec2cc

5 files changed

+96
-6
lines changed

.coveragerc

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[report]
2+
3+
show_missing = True
4+
5+
exclude_lines =
6+
if __name__ == .__main__.:
7+

.flake8

+3-6
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ jobs = auto
3232

3333
########## VERBOSITY ##########
3434

35-
# Increase the verbosity of Flake8's output.
35+
# Increase the verbosity of Flake8s output.
3636
verbose = 0
37-
# Decrease the verbosity of Flake8's output.
37+
# Decrease the verbosity of Flake8s output.
3838
quiet = 0
3939

4040

@@ -91,7 +91,7 @@ disable-noqa = False
9191
max-line-length = 100
9292
# Set the maximum allowed McCabe complexity value for a block of code.
9393
max-complexity = 10
94-
# Toggle whether pycodestyle should enforce matching the indentation of the opening bracket's line.
94+
# Toggle whether pycodestyle should enforce matching the indentation of the opening brackets line.
9595
# incluences E131 and E133
9696
hang-closing = True
9797

@@ -107,8 +107,6 @@ hang-closing = True
107107
# Specify a list of codes to ignore.
108108
ignore = D4
109109
# Specify the list of error codes you wish Flake8 to report.
110-
# For now we only use the pyflakes errors, but in the future we may want to add
111-
# more (too noisy right now)
112110
select = F, E9
113111
# Enable off-by-default extensions.
114112
enable-extensions =
@@ -127,4 +125,3 @@ exclude-in-doctest =
127125
# tell flake8-rst-docstrings plugin to ignore some custom roles
128126
# this prevents FP RST303 and RST304
129127
rst-roles = py:meth, py:class, py:obj
130-

.gitlab-ci.yml

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
stages:
2+
- test
3+
- export
4+
5+
test_module:
6+
stage: test
7+
image: python:3.7-slim
8+
script:
9+
- pip install -r requirements-dev.txt
10+
- flake8 src/
11+
- pip install -r requirements.txt
12+
- pip install .
13+
- pytest --cov=retypd --cov-config=.coveragerc test/
14+
tags:
15+
- kubernetes
16+
rules:
17+
- if: '$CI_COMMIT_BRANCH || $CI_MERGE_REQUEST_REF_PATH'
18+
19+
export_module:
20+
stage: export
21+
image: python:3.7-slim
22+
script:
23+
- pip install -r requirements-dev.txt
24+
- python3 setup.py bdist_wheel --dist-dir=$CI_PROJECT_DIR/dist
25+
- ls $CI_PROJECT_DIR/dist/*.whl | xargs $CI_PROJECT_DIR/delete_remote_packages.py $GL_PKG_API_TOKEN
26+
- sed "s/password = <access token>/password = $GL_PKG_API_TOKEN/" $CI_PROJECT_DIR/.pypirc > ~/.pypirc
27+
- python3 -m twine upload --verbose --repository repypi $CI_PROJECT_DIR/dist/*.whl
28+
tags:
29+
- kubernetes
30+
rules:
31+
- if: '$CI_COMMIT_BRANCH == "master"'
32+
- if: '$CI_COMMIT_REF_NAME =~ /^release-.*/'

.pypirc

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[distutils]
2+
index-servers =
3+
repypi
4+
[repypi]
5+
repository = https://git.grammatech.com/api/v4/projects/1587/packages/pypi
6+
username = __token__
7+
password = <access token>

delete_remote_packages.py

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#!/usr/bin/env python
2+
"""
3+
Helper script for working around a "feature" in Gitlab's pypi package repositories.
4+
Pypi does not support uploading packages of the same version,
5+
they believe the version should be bumped for any change.
6+
We're going to delete packages instead.
7+
8+
Call this script with positional args.
9+
The first is the token with read and write access to the pypi repository.
10+
This can be your personal access token or $CI_DEPLOY_PASSWORD.
11+
$CI_JOB_TOKEN does not work, it doesn't have write access.
12+
The remainder is an unlimited list of wheels to be uploaded.
13+
14+
If any local wheels find a match in name and version in the remote pypi repository, the remote will be deleted.
15+
"""
16+
import sys
17+
import requests
18+
import pkginfo
19+
20+
TOKEN = sys.argv[1]
21+
for wheel_loc in sys.argv[2:]:
22+
wheel = pkginfo.Wheel(wheel_loc)
23+
# Get packages, handling pagination
24+
responses = []
25+
response = requests.get(
26+
f'https://git.grammatech.com/api/v4/projects/1587/packages?package_name={wheel.name}',
27+
headers={'PRIVATE-TOKEN': TOKEN},
28+
)
29+
responses.append(response)
30+
while response.links.get('next'):
31+
response = requests.get(response.links.get('next')['url'],
32+
headers={'PRIVATE-TOKEN': TOKEN})
33+
if response.status_code != 200:
34+
raise Exception(f'{response.status_code} status code while requesting package listings filtered by local name: {wheel.name}')
35+
responses.append(response)
36+
37+
packages = [package for response in responses for package in response.json()]
38+
# Delete all matching packages
39+
for package in packages:
40+
if wheel.version == package['version'] and wheel.name == package['name']:
41+
print(f'Deleting {package["name"]} {package["version"]}.')
42+
response = requests.delete(
43+
f'https://git.grammatech.com/api/v4/projects/1587/packages/{package["id"]}',
44+
headers={'PRIVATE-TOKEN': TOKEN},
45+
)
46+
if response.status_code != 204:
47+
raise Exception(f'{response.status_code} status code while deleting this package: {package["name"]} {package["version"]}')

0 commit comments

Comments
 (0)