Skip to content

Commit 19253db

Browse files
authored
Merge pull request #196 from cloudblue/LITE-26441-fix-bump-error-backport
LITE-26441: Fixed bump cmd.
2 parents 65d2d6a + efef166 commit 19253db

File tree

2 files changed

+121
-9
lines changed

2 files changed

+121
-9
lines changed

connect/cli/plugins/project/extension/helpers.py

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -176,22 +176,68 @@ def validate_extension_project(config, project_dir): # noqa: CCR001
176176
console.secho(f'Extension Project {project_dir} has been successfully validated.', fg='green')
177177

178178

179-
def bump_runner_extension_project(project_dir: str):
179+
def _update_docker_file_runner_from(dockerfile: str, latest_version: str):
180+
to_be_replaced = False
181+
last_runner = f'cloudblueconnect/connect-extension-runner:{latest_version}'
182+
lines = []
183+
with open(dockerfile, 'r') as f:
184+
for line in f.readlines():
185+
content = line.split()
186+
if (
187+
content[0] == 'FROM'
188+
and content[1].startswith(
189+
'cloudblueconnect/connect-extension-runner:',
190+
)
191+
and content[1].strip() != last_runner
192+
):
193+
lines.append(line.replace(content[1], last_runner))
194+
to_be_replaced = True
195+
else:
196+
lines.append(line)
197+
if to_be_replaced:
198+
with open(dockerfile, 'w') as f:
199+
f.writelines(lines)
200+
return to_be_replaced
201+
202+
203+
def bump_runner_extension_project(project_dir: str): # noqa: CCR001
180204
console.secho(f'Bumping runner version on project {project_dir}...\n', fg='blue')
181205

206+
updated_files = set()
182207
latest_version = get_pypi_runner_version()
208+
latest_runner_version = f'cloudblueconnect/connect-extension-runner:{latest_version}'
183209
docker_compose_file = os.path.join(project_dir, 'docker-compose.yml')
184210
if not os.path.isfile(docker_compose_file):
185211
raise ClickException(f'Mandatory `docker-compose.yml` file on directory `{project_dir}` is missing.')
186212
try:
187213
with open(docker_compose_file, 'r') as file_reader:
188214
data = yaml.load(file_reader, Loader=yaml.FullLoader)
189215
for service in data['services']:
190-
if 'image' in data['services'][service]:
216+
if (
217+
'image' in data['services'][service]
218+
and data['services'][service]['image'].startswith(
219+
'cloudblueconnect/connect-extension-runner:',
220+
)
221+
and data['services'][service]['image'] != latest_runner_version
222+
):
191223
runner_image = data['services'][service]['image']
192224
runner_version = runner_image.split(':')[-1]
193225
updated_image = runner_image.replace(runner_version, latest_version)
194226
data['services'][service]['image'] = updated_image
227+
updated_files.add(docker_compose_file)
228+
elif 'build' in data['services'][service]:
229+
dockerfile = data['services'][service]['build'].get('dockerfile', 'Dockerfile')
230+
dockerfile_path = os.path.join(project_dir, dockerfile)
231+
if not os.path.isfile(dockerfile_path):
232+
raise ClickException(
233+
f'The expected dockerfile `{dockerfile_path}` specified in '
234+
f'{docker_compose_file} is missing.',
235+
)
236+
if (
237+
dockerfile_path not in updated_files
238+
and _update_docker_file_runner_from(dockerfile_path, latest_version)
239+
):
240+
updated_files.add(dockerfile_path)
195241
with open(docker_compose_file, 'w') as file_writer:
196242
yaml.dump(data, file_writer, sort_keys=False)
197243
except yaml.YAMLError as error:
@@ -200,4 +246,11 @@ def bump_runner_extension_project(project_dir: str):
200246
f'Error: {error}',
201247
)
202248

203-
console.secho(f'Runner version has been successfully updated to {latest_version}', fg='green')
249+
if updated_files:
250+
console.secho(
251+
f'Runner version has been successfully updated to {latest_version}. The following '
252+
f'files have been updated:\n{",".join(updated_files)}',
253+
fg='green',
254+
)
255+
else:
256+
console.secho(f'Nothing to update to {latest_version}', fg='yellow')

tests/plugins/project/test_extension_helpers.py

Lines changed: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -681,21 +681,80 @@ def test_bootstrap_extension_project_if_destination_exists(mocker):
681681

682682

683683
def test_bump_runner_version(mocker, capsys):
684+
_mock_pypi_version(mocker)
685+
with tempfile.TemporaryDirectory() as tmp_data:
686+
project_dir = f'{tmp_data}/project'
687+
os.mkdir(project_dir)
688+
docker_compose = {
689+
'services': {
690+
'dev': {'container_name': 'ext_dev', 'image': 'cloudblueconnect/connect-extension-runner:0.5'},
691+
'test': {'container_name': 'ext_test', 'image': 'cloudblueconnect/connect-extension-runner:0.5'},
692+
'si': {'container_name': 'ext_si', 'build': {'dockerfile': f'{project_dir}/OtherDockerfile'}},
693+
'prod': {'container_name': 'ext_prod', 'build': {'context': '.'}},
694+
},
695+
}
696+
with open(f'{project_dir}/docker-compose.yml', 'w') as fp:
697+
yaml.dump(docker_compose, fp)
698+
with open(f'{project_dir}/Dockerfile', 'w') as fp:
699+
fp.write('FROM cloudblueconnect/connect-extension-runner:0.5')
700+
with open(f'{project_dir}/OtherDockerfile', 'w') as fp:
701+
fp.write('FROM cloudblueconnect/connect-extension-runner:0.5')
702+
bump_runner_extension_project(project_dir)
703+
captured = capsys.readouterr()
704+
assert 'Runner version has been successfully updated to 1.0' in captured.out
705+
assert f'{os.path.join(project_dir, "docker-compose.yml")}' in captured.out
706+
assert f'{os.path.join(project_dir, "OtherDockerfile")}' in captured.out
707+
assert f'{os.path.join(project_dir, "Dockerfile")}' in captured.out
708+
709+
710+
def test_bump_runner_version_no_update_required(mocker, capsys):
711+
_mock_pypi_version(mocker)
712+
with tempfile.TemporaryDirectory() as tmp_data:
713+
project_dir = f'{tmp_data}/project'
714+
os.mkdir(project_dir)
715+
docker_compose = {
716+
'services': {
717+
'dev': {'container_name': 'ext_dev', 'image': 'cloudblueconnect/connect-extension-runner:1.0'},
718+
'test': {'container_name': 'ext_test', 'image': 'cloudblueconnect/connect-extension-runner:1.0'},
719+
'si': {'container_name': 'ext_si', 'build': {'dockerfile': f'{project_dir}/OtherDockerfile'}},
720+
'prod': {'container_name': 'ext_prod', 'build': {}},
721+
},
722+
}
723+
with open(f'{project_dir}/docker-compose.yml', 'w') as dc:
724+
yaml.dump(docker_compose, dc)
725+
with open(f'{project_dir}/Dockerfile', 'w') as df:
726+
df.write('FROM cloudblueconnect/connect-extension-runner:1.0')
727+
df.write('\n')
728+
with open(f'{project_dir}/OtherDockerfile', 'w') as df2:
729+
df2.write('FROM cloudblueconnect/connect-extension-runner:1.0')
730+
df2.write('\n')
731+
bump_runner_extension_project(project_dir)
732+
captured = capsys.readouterr()
733+
assert 'Nothing to update to 1.0' in captured.out
734+
735+
736+
def test_bump_runner_version_invalid_dockerfile(mocker):
684737
_mock_pypi_version(mocker)
685738
docker_compose = {
686739
'services': {
687-
'dev': {'container_name': 'ext_dev', 'image': 'runner:0.5'},
688-
'test': {'container_name': 'ext_test', 'image': 'runner:0.5'},
740+
'dev': {
741+
'container_name': 'ext_dev',
742+
'build': {'dockerfile': 'invalidfile'},
743+
},
689744
},
690745
}
691746
with tempfile.TemporaryDirectory() as tmp_data:
692747
project_dir = f'{tmp_data}/project'
693748
os.mkdir(project_dir)
694-
with open(f'{project_dir}/docker-compose.yml', 'w') as fp:
749+
dc = f'{project_dir}/docker-compose.yml'
750+
with open(dc, 'w') as fp:
695751
yaml.dump(docker_compose, fp)
696-
bump_runner_extension_project(project_dir)
697-
captured = capsys.readouterr()
698-
assert 'Runner version has been successfully updated' in captured.out
752+
with pytest.raises(ClickException) as exc:
753+
bump_runner_extension_project(project_dir)
754+
assert (
755+
f'The expected dockerfile `{project_dir}/invalidfile` specified in '
756+
f'{dc} is missing.'
757+
) in str(exc)
699758

700759

701760
def test_bump_runner_docker_compose_not_found(mocker):

0 commit comments

Comments
 (0)