Skip to content

Commit 3a38c6d

Browse files
authored
Merge pull request #1202 from python-gitlab/fix/cli-binary-data
fix(cli): write binary data to stdout buffer
2 parents bc17889 + f4e7950 commit 3a38c6d

File tree

5 files changed

+107
-6
lines changed

5 files changed

+107
-6
lines changed

docs/cli-usage.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,12 @@ Define the status of a commit (as would be done from a CI tool for example):
313313
--target-url http://server/build/123 \
314314
--description "Jenkins build succeeded"
315315
316+
Download the artifacts zip archive of a job:
317+
318+
.. code-block:: console
319+
320+
$ gitlab project-job artifacts --id 10 --project-id 1 > artifacts.zip
321+
316322
Use sudo to act as another user (admin only):
317323

318324
.. code-block:: console

gitlab/v4/cli.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,7 @@ def do_project_export_download(self):
8585
try:
8686
project = self.gl.projects.get(int(self.args["project_id"]), lazy=True)
8787
data = project.exports.get().download()
88-
if hasattr(sys.stdout, "buffer"):
89-
# python3
90-
sys.stdout.buffer.write(data)
91-
else:
92-
sys.stdout.write(data)
88+
sys.stdout.buffer.write(data)
9389

9490
except Exception as e:
9591
cli.die("Impossible to download the export", e)
@@ -440,5 +436,7 @@ def run(gl, what, action, args, verbose, output, fields):
440436
printer.display(get_dict(data, fields), verbose=verbose, obj=data)
441437
elif isinstance(data, str):
442438
print(data)
439+
elif isinstance(data, bytes):
440+
sys.stdout.buffer.write(data)
443441
elif hasattr(data, "decode"):
444442
print(data.decode())
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import subprocess
2+
import sys
3+
import textwrap
4+
import time
5+
from io import BytesIO
6+
from zipfile import is_zipfile
7+
8+
import pytest
9+
10+
11+
content = textwrap.dedent(
12+
"""\
13+
test-artifact:
14+
script: echo "test" > artifact.txt
15+
artifacts:
16+
untracked: true
17+
"""
18+
)
19+
data = {
20+
"file_path": ".gitlab-ci.yml",
21+
"branch": "master",
22+
"content": content,
23+
"commit_message": "Initial commit",
24+
}
25+
26+
27+
@pytest.mark.skipif(sys.version_info < (3, 8), reason="I am the walrus")
28+
def test_cli_artifacts(capsysbinary, gitlab_config, gitlab_runner, project):
29+
project.files.create(data)
30+
31+
while not (jobs := project.jobs.list(scope="success")):
32+
time.sleep(0.5)
33+
34+
job = project.jobs.get(jobs[0].id)
35+
cmd = [
36+
"gitlab",
37+
"--config-file",
38+
gitlab_config,
39+
"project-job",
40+
"artifacts",
41+
"--id",
42+
str(job.id),
43+
"--project-id",
44+
str(project.id),
45+
]
46+
47+
with capsysbinary.disabled():
48+
artifacts = subprocess.check_output(cmd)
49+
assert isinstance(artifacts, bytes)
50+
51+
artifacts_zip = BytesIO(artifacts)
52+
assert is_zipfile(artifacts_zip)

tools/functional/conftest.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,36 @@ def gl(gitlab_config):
132132
return instance
133133

134134

135+
@pytest.fixture(scope="session")
136+
def gitlab_runner(gl):
137+
container = "gitlab-runner-test"
138+
runner_name = "python-gitlab-runner"
139+
token = "registration-token"
140+
url = "http://gitlab"
141+
142+
docker_exec = ["docker", "exec", container, "gitlab-runner"]
143+
register = [
144+
"register",
145+
"--run-untagged",
146+
"--non-interactive",
147+
"--registration-token",
148+
token,
149+
"--name",
150+
runner_name,
151+
"--url",
152+
url,
153+
"--clone-url",
154+
url,
155+
"--executor",
156+
"shell",
157+
]
158+
unregister = ["unregister", "--name", runner_name]
159+
160+
yield check_output(docker_exec + register).decode()
161+
162+
check_output(docker_exec + unregister).decode()
163+
164+
135165
@pytest.fixture(scope="module")
136166
def group(gl):
137167
"""Group fixture for group API resource tests."""

tools/functional/fixtures/docker-compose.yml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
version: '3'
2+
3+
networks:
4+
gitlab-network:
5+
name: gitlab-network
6+
27
services:
38
gitlab:
49
image: '${GITLAB_IMAGE}:${GITLAB_TAG}'
@@ -9,7 +14,7 @@ services:
914
GITLAB_OMNIBUS_CONFIG: |
1015
external_url 'http://gitlab.test'
1116
gitlab_rails['initial_root_password'] = '5iveL!fe'
12-
gitlab_rails['initial_shared_runners_registration_token'] = 'sTPNtWLEuSrHzoHP8oCU'
17+
gitlab_rails['initial_shared_runners_registration_token'] = 'registration-token'
1318
registry['enable'] = false
1419
nginx['redirect_http_to_https'] = false
1520
nginx['listen_port'] = 80
@@ -29,3 +34,13 @@ services:
2934
ports:
3035
- '8080:80'
3136
- '2222:22'
37+
networks:
38+
- gitlab-network
39+
40+
gitlab-runner:
41+
image: gitlab/gitlab-runner:latest
42+
container_name: 'gitlab-runner-test'
43+
depends_on:
44+
- gitlab
45+
networks:
46+
- gitlab-network

0 commit comments

Comments
 (0)