canonical / craft-application

The basis for *craft applications
https://canonical-craft-application.readthedocs-hosted.com/en/latest
GNU Lesser General Public License v3.0
5 stars 6 forks source link

Advanced grammar cannot be used with secrets #333

Open mr-cal opened 1 month ago

mr-cal commented 1 month ago

Bug Description

Advanced grammar in source and build-environment cannot be used when the secrets feature is enabled.

_render_part_secrets() fails because it does not expect grammar dictionaries.

To Reproduce

Use the yaml below in this unit test fixture:

https://github.com/canonical/craft-application/blob/6a3026352d71c3dd44489764032079c4b9d6cb5e/tests/unit/test_application.py#L1165

part yaml

name: myproject
version: 1.2.3
parts:
  mypart:
    plugin: nil
    source:
      - on amd64 to riscv64: $(HOST_SECRET:echo ${SECRET_VAR_1})/riscv64-src
      - on amd64 to s390x: $(HOST_SECRET:echo ${SECRET_VAR_1})/s390x-src
    build-environment:
      - on amd64 to riscv64:
        - MY_VAR: $(HOST_SECRET:echo ${SECRET_VAR_3})
      - on amd64 to s390x:
        - MY_VAR: $(HOST_SECRET:echo ${SECRET_VAR_4})

Relevant log output

app_metadata = AppMetadata(name='testcraft', summary='A fake app for testing craft-application', version='3.14159', source_ignore_pat...ectClass=<class 'craft_application.models.project.Project'>, BuildPlannerClass=<class 'tests.conftest.MyBuildPlanner'>)
fake_services = ServiceFactory(app=AppMetadata(name='testcraft', summary='A fake app for testing craft-application', version='3.14159'...aft-application'), license='LGPLv3', adopt_info=None, parts={'my-part': {'plugin': 'nil'}}, package_repositories=None))
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7d877205af90>, mocker = <pytest_mock.plugin.MockerFixture object at 0x7d8771fa2f90>

    @pytest.mark.usefixtures("build_secrets_project")
    @pytest.mark.enable_features("build_secrets")
    def test_application_build_secrets(app_metadata, fake_services, monkeypatch, mocker):
        monkeypatch.setenv("SECRET_VAR_1", "source-folder")
        monkeypatch.setenv("SECRET_VAR_2", "secret-value")
        spied_set_secrets = mocker.spy(craft_cli.emit, "set_secrets")

        app = application.Application(app_metadata, fake_services)
>       project = app.get_project(build_for=get_host_architecture())

/home/developer/dev/craft-application/tests/unit/test_application.py:1201:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/home/developer/dev/craft-application/craft_application/application.py:296: in get_project
    yaml_data = self._transform_project_yaml(yaml_data, build_on, build_for)
/home/developer/dev/craft-application/craft_application/application.py:590: in _transform_project_yaml
    self._render_secrets(yaml_data)
/home/developer/dev/craft-application/craft_application/application.py:662: in _render_secrets
    secret_values = secrets.render_secrets(
/home/developer/dev/craft-application/craft_application/secrets.py:70: in render_secrets
    _render_part_secrets(part, command_cache, managed_mode)
/home/developer/dev/craft-application/craft_application/secrets.py:88: in _render_part_secrets
    if (rendered := _render_secret(source, command_cache, managed_mode)) is not None:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

yaml_string = [{'on amd64 to riscv64': '$(HOST_SECRET:echo ${SECRET_VAR_1})/riscv64-src'}, {'on amd64 to s390x': '$(HOST_SECRET:echo ${SECRET_VAR_1})/s390x-src'}], command_cache = {}
managed_mode = False

    def _render_secret(
        yaml_string: str,
        command_cache: dict[str, str],
        managed_mode: bool,  # noqa: FBT001 (boolean positional arg)
    ) -> str | None:
>       if match := SECRET_REGEX.search(yaml_string):
E       TypeError: expected string or bytes-like object, got 'list'

/home/developer/dev/craft-application/craft_application/secrets.py:106: TypeError
---------------------------------------------------------------------------------------- Captured log call -----------------------------------------------------------------------------------------
DEBUG    craft_parts.infos:infos.py:330 Setting target machine to x86_64
===================================================================================== short test summary info ======================================================================================
FAILED tests/unit/test_application.py::test_application_build_secrets - TypeError: expected string or bytes-like object, got 'list'
syncronize-issues-to-jira[bot] commented 1 month ago

Thank you for reporting us your feedback!

The internal ticket has been created: https://warthogs.atlassian.net/browse/CRAFT-2864.

This message was autogenerated