From c8345bc11635b2aacc92a63bda2291ba547651ff Mon Sep 17 00:00:00 2001 From: Callahan Kovacs Date: Thu, 23 Jan 2025 15:19:41 -0600 Subject: [PATCH 1/7] feat(remotebuild): filter build-plan with --platform or --build-for Allows using '--platform' or '--build-for' to filter entries in the 'architectures' or 'platforms' keys in a project file. If the project file doesn't contain an 'architectures' or 'platforms' entry, then '--platform' and '--build-for' define the architectures to build for. Signed-off-by: Callahan Kovacs --- docs/explanation/remote-build.rst | 19 +- snapcraft/application.py | 10 +- snapcraft/commands/remote.py | 180 +++++++++++------- .../architectures-filtered/arguments.txt | 1 + .../architectures-filtered/expected-snaps.txt | 1 + .../architectures-filtered/snapcraft.yaml | 18 ++ tests/spread/core22/remote-build/task.yaml | 1 + .../snaps/platforms-filtered/arguments.txt | 1 + .../platforms-filtered/expected-snaps.txt | 1 + .../snaps/platforms-filtered/snapcraft.yaml | 20 ++ tests/spread/core24/remote-build/task.yaml | 10 +- tests/unit/commands/test_remote.py | 114 +++++++++-- tests/unit/test_application.py | 12 +- 13 files changed, 291 insertions(+), 97 deletions(-) create mode 100644 tests/spread/core22/remote-build/snaps/architectures-filtered/arguments.txt create mode 100644 tests/spread/core22/remote-build/snaps/architectures-filtered/expected-snaps.txt create mode 100644 tests/spread/core22/remote-build/snaps/architectures-filtered/snapcraft.yaml create mode 100644 tests/spread/core24/remote-build/snaps/platforms-filtered/arguments.txt create mode 100644 tests/spread/core24/remote-build/snaps/platforms-filtered/expected-snaps.txt create mode 100644 tests/spread/core24/remote-build/snaps/platforms-filtered/snapcraft.yaml diff --git a/docs/explanation/remote-build.rst b/docs/explanation/remote-build.rst index 9e95faad52..c41031cd9b 100644 --- a/docs/explanation/remote-build.rst +++ b/docs/explanation/remote-build.rst @@ -89,12 +89,20 @@ Current ``--platform`` and ``--build-for`` behave differently than they do for :ref:`lifecycle commands`. -``--platform`` or ``--build-for`` can only be provided when the ``platforms`` -or ``architectures`` keywords are not defined in the project metadata -(`[12]`_). +If the project file contains a ``platforms`` or ``architectures`` key, then +``--platform`` or ``--build-for`` filter the build plan defined by that key. +For more information about build plans and filtering, see +:ref:`Build plans `. -These keywords are mutually exclusive and must be a comma-separated list of -debian architectures. +If the project file doesn't contain a ``platforms`` or ``architectures`` entry, +then ``--platform`` or ``--build-for`` define the architectures to build for. + +It the project file doesn't contain a ``platforms`` or ``architectures`` entry +and ``--platform`` or ``--build-for`` are not provided, Snapcraft will build +for the host system's architecture. + +These ``--platform`` and ``--build-for`` arguments are mutually exclusive and +must be a comma-separated list of debian architectures. ``core22`` snaps can only use ``--build-for``. ``core24`` and newer snaps can use ``--platform`` or ``--build-for``. @@ -180,6 +188,5 @@ Launchpad is not able to parse this notation (`[9]`_). .. _`[8]`: https://bugs.launchpad.net/snapcraft/+bug/2007789 .. _`[9]`: https://bugs.launchpad.net/snapcraft/+bug/2042167 .. _`[10]`: https://github.com/canonical/snapcraft/issues/4885 -.. _`[12]`: https://github.com/canonical/snapcraft/issues/4992 .. _`[13]`: https://github.com/canonical/snapcraft/issues/4996 .. _`[14]`: https://github.com/canonical/snapcraft/issues/4995 diff --git a/snapcraft/application.py b/snapcraft/application.py index 836e2e4801..1e747689df 100644 --- a/snapcraft/application.py +++ b/snapcraft/application.py @@ -27,7 +27,7 @@ import craft_cli import craft_parts import craft_store -from craft_application import Application, AppMetadata, remote, util +from craft_application import Application, AppMetadata, launchpad, remote, util from craft_application.commands import get_other_command_group from craft_cli import emit from craft_parts.plugins.plugins import PluginType @@ -224,6 +224,14 @@ def _run_inner(self) -> int: err.doc_slug = "/explanation/remote-build" self._emit_error(err) return_code = err.retcode + except launchpad.LaunchpadError as err: + self._emit_error( + craft_cli.errors.CraftError( + f"{err}", doc_slug="/explanation/remote-build" + ), + cause=err, + ) + return_code = 1 return return_code diff --git a/snapcraft/commands/remote.py b/snapcraft/commands/remote.py index a38ea34a1f..3e96610ee3 100644 --- a/snapcraft/commands/remote.py +++ b/snapcraft/commands/remote.py @@ -24,14 +24,17 @@ from pathlib import Path from typing import Any, cast +import craft_application.errors import lazr.restfulclient.errors -from craft_application import errors +from craft_application import errors, launchpad +from craft_application.application import filter_plan from craft_application.commands import ExtensibleCommand from craft_application.errors import RemoteBuildError from craft_application.launchpad.models import Build, BuildState from craft_application.remote.utils import get_build_id from craft_application.util import humanize_list from craft_cli import emit +from craft_platforms import DebianArchitecture from overrides import overrides from snapcraft import models @@ -57,9 +60,16 @@ class RemoteBuildCommand(ExtensibleCommand): architecture are retrieved and will be available in the local filesystem. - If not specified in the snapcraft.yaml file, the list of - architectures to build can be set using the --platforms option. - If both are specified, an error will occur. + If the project contains a ``platforms`` or ``architectures`` key, + then project's build plan is used. The build plan can be filtered + using the ``--platform`` or ``--build-for`` arguments. + + If the project doesn't contain a ``platforms`` or ``architectures`` key, + then the architectures to build for are defined by the ``--platform`` or + ``--build-for`` arguments. + + If there are no architectures defined in the project or as arguments, + then the default behavior is to build for the host architecture. Interrupted remote builds can be resumed using the --recover option, followed by the build number informed when the remote @@ -154,56 +164,17 @@ def _validate(self, parsed_args: argparse.Namespace) -> None: retcode=os.EX_NOPERM, ) - build_fors = parsed_args.remote_build_build_fors or None - platforms = parsed_args.remote_build_platforms or None - parameter = "--build-for" if build_fors else "--platform" if platforms else None - keyword = ( - "architectures" - if self.project._architectures_in_yaml - else "platforms" if self.project.platforms else None - ) - - if keyword and parameter: + if ( + parsed_args.remote_build_platforms + and self.project.get_effective_base() == "core22" + ): raise errors.RemoteBuildError( - f"{parameter!r} cannot be used when {keyword!r} is in the snapcraft.yaml.", - resolution=f"Remove {parameter!r} from the command line or remove {keyword!r} in the snapcraft.yaml.", + "'--platform' cannot be used for core22 snaps.", + resolution="Use '--build-for' instead.", doc_slug="/explanation/remote-build.html", retcode=os.EX_CONFIG, ) - if platforms: - if self.project.get_effective_base() == "core22": - raise errors.RemoteBuildError( - "'--platform' cannot be used for core22 snaps.", - resolution="Use '--build-for' instead.", - doc_slug="/explanation/remote-build.html", - retcode=os.EX_CONFIG, - ) - for platform in platforms: - if platform not in SUPPORTED_ARCHS: - raise errors.RemoteBuildError( - f"Unsupported platform {platform!r}.", - resolution=( - "Use a supported debian architecture. Supported " - f"architectures are: {humanize_list(SUPPORTED_ARCHS, 'and')}" - ), - doc_slug="/explanation/remote-build.html", - retcode=os.EX_CONFIG, - ) - - if build_fors: - for build_for in build_fors: - if build_for not in SUPPORTED_ARCHS: - raise errors.RemoteBuildError( - f"Unsupported build-for architecture {build_for!r}.", - resolution=( - "Use a supported debian architecture. Supported " - f"architectures are: {humanize_list(SUPPORTED_ARCHS, 'and')}" - ), - doc_slug="/explanation/remote-build.html", - retcode=os.EX_CONFIG, - ) - self._validate_single_artifact_per_build_on() def _validate_single_artifact_per_build_on(self) -> None: @@ -274,14 +245,10 @@ def _run( # noqa: PLR0915 [too-many-statements] emit.trace(f"Project directory: {project_dir}") self._validate(parsed_args) - if parsed_args.remote_build_build_fors: - architectures = parsed_args.remote_build_build_fors - elif parsed_args.remote_build_platforms: - architectures = parsed_args.remote_build_platforms - else: - architectures = self._get_project_build_fors() - - emit.debug(f"Architectures to build for: {architectures}") + archs = self._get_archs( + build_fors=parsed_args.remote_build_build_fors, + platforms=parsed_args.remote_build_platforms, + ) if parsed_args.launchpad_timeout: emit.debug(f"Setting timeout to {parsed_args.launchpad_timeout} seconds") @@ -296,10 +263,8 @@ def _run( # noqa: PLR0915 [too-many-statements] "Starting new build. It may take a while to upload large projects." ) try: - builds = builder.start_builds( - project_dir, architectures=architectures or None - ) - except RemoteBuildError: + builds = builder.start_builds(project_dir, architectures=archs) + except (RemoteBuildError, launchpad.LaunchpadError): emit.progress("Starting build failed.", permanent=True) emit.progress("Cleaning up") builder.cleanup() @@ -407,12 +372,95 @@ def _monitor_and_complete( # noqa: PLR0912, PLR0915 ) return return_code - def _get_project_build_fors(self) -> list[str]: - """Get a unique list of build-for architectures from the project. + def _get_archs(self, build_fors: list[str], platforms: list[str]) -> list[str]: + """Get the architectures to build for. + + If the project contains a ``platforms`` or ``architectures`` key, then project's + build plan is used to determine the architectures to build for. The build plan + can be filtered using the ``--platform`` or ``--build-for`` arguments. + + If the project doesn't contain a ``platforms`` or ``architectures`` key, then + the architectures to build for are defined by the ``--platform`` or + ``--build-for`` arguments. + + If there are no architectures defined in the project or as arguments, then the + default behavior is to build for the host architecture. + + :param build_fors: A list of build-for entries. + :param platforms: A list of platforms. + + :raises EmptyBuildPlanError: If the build plan is filtered to an empty list. + :raises RemoteBuildError: If an unsupported architecture is provided. :returns: A list of architectures. """ - build_fors = set({build_info.build_for for build_info in self.build_plan}) - emit.debug(f"Parsed build-for architectures from build plan: {build_fors}") + archs: list[str] = [] + # core22 projects with an `architectures` key will have a corresponding `platforms` + # key when the project is unmarshalled + if self.project.platforms or self.project._architectures_in_yaml: + # if the project has platforms, then the `--platforms` and `--build-for` arguments act as filters + if build_fors: + emit.debug("Filtering the build plan using the '--build-for' argument.") + for build_for in build_fors: + filtered_build_plan = filter_plan( + self.build_plan, + platform=None, + build_for=build_for, + host_arch=None, + ) + archs.extend([info.build_for for info in filtered_build_plan]) + if not archs: + raise craft_application.errors.EmptyBuildPlanError() + elif platforms: + emit.debug("Filtering the build plan using the '--platforms' argument.") + for platform in platforms: + filtered_build_plan = filter_plan( + self.build_plan, + platform=platform, + build_for=None, + host_arch=None, + ) + archs.extend([info.build_for for info in filtered_build_plan]) + if not archs: + raise craft_application.errors.EmptyBuildPlanError() + else: + emit.debug("Using the project's build plan") + archs = [build_info.build_for for build_info in self.build_plan] + # No platforms in the project means '--build-for' and '--platforms' no longer act as filters. + # Instead, they define the architectures to build for. + elif build_fors: + emit.debug("Using '--build-for' as the list of architectures to build for") + _validate_archs(build_fors, "build-for architecture") + archs = build_fors + elif platforms: + emit.debug("Using '--platforms' as the list of architectures to build for") + _validate_archs(platforms, "platform") + archs = platforms + # default is to build for the host architecture + else: + archs = [str(DebianArchitecture.from_host())] + emit.debug( + f"Using host architecture {archs[0]} because no architectures were " + "defined in the project or as a command-line argument." + ) + + emit.debug(f"Architectures to build for: {humanize_list(archs, 'and')}") + return archs - return list(build_fors) + +def _validate_archs(archs: list[str], key_name: str) -> None: + """Validate that a list of architectures are valid. + + :raises RemoteBuildError: If an unsupported architecture is provided. + """ + for arch in archs: + if arch not in SUPPORTED_ARCHS: + raise errors.RemoteBuildError( + f"Unsupported {key_name} {arch!r}.", + resolution=( + "Use a supported debian architecture. Supported " + f"architectures are: {humanize_list(SUPPORTED_ARCHS, 'and')}" + ), + doc_slug="/explanation/remote-build.html", + retcode=os.EX_CONFIG, + ) diff --git a/tests/spread/core22/remote-build/snaps/architectures-filtered/arguments.txt b/tests/spread/core22/remote-build/snaps/architectures-filtered/arguments.txt new file mode 100644 index 0000000000..2bbc7b956e --- /dev/null +++ b/tests/spread/core22/remote-build/snaps/architectures-filtered/arguments.txt @@ -0,0 +1 @@ +--build-for amd64 diff --git a/tests/spread/core22/remote-build/snaps/architectures-filtered/expected-snaps.txt b/tests/spread/core22/remote-build/snaps/architectures-filtered/expected-snaps.txt new file mode 100644 index 0000000000..24a021e27a --- /dev/null +++ b/tests/spread/core22/remote-build/snaps/architectures-filtered/expected-snaps.txt @@ -0,0 +1 @@ +test-snap-architectures-filtered-core22_1.0_amd64.snap diff --git a/tests/spread/core22/remote-build/snaps/architectures-filtered/snapcraft.yaml b/tests/spread/core22/remote-build/snaps/architectures-filtered/snapcraft.yaml new file mode 100644 index 0000000000..d7b5d5a761 --- /dev/null +++ b/tests/spread/core22/remote-build/snaps/architectures-filtered/snapcraft.yaml @@ -0,0 +1,18 @@ +name: test-snap-architectures-filtered-core22 +base: core22 +version: "1.0" +summary: Test snap for remote build +description: Test snap for remote build + +grade: stable +confinement: strict + +architectures: + - build-on: [amd64] + build-for: [amd64] + - build-on: [riscv64] + build-for: [riscv64] + +parts: + my-part: + plugin: nil diff --git a/tests/spread/core22/remote-build/task.yaml b/tests/spread/core22/remote-build/task.yaml index feee247997..3b2d9a08f2 100644 --- a/tests/spread/core22/remote-build/task.yaml +++ b/tests/spread/core22/remote-build/task.yaml @@ -8,6 +8,7 @@ environment: SNAP/all: all SNAP/no_architectures: no-architectures SNAP/architectures: architectures + SNAP/architectures_filtered: architectures-filtered SNAP/build_for_arg: build-for-arg SNAPCRAFT_REMOTE_BUILD_STRATEGY: disable-fallback CREDENTIALS_FILE: "$HOME/.local/share/snapcraft/launchpad-credentials" diff --git a/tests/spread/core24/remote-build/snaps/platforms-filtered/arguments.txt b/tests/spread/core24/remote-build/snaps/platforms-filtered/arguments.txt new file mode 100644 index 0000000000..c2bfcf76fd --- /dev/null +++ b/tests/spread/core24/remote-build/snaps/platforms-filtered/arguments.txt @@ -0,0 +1 @@ +--platform amd64 diff --git a/tests/spread/core24/remote-build/snaps/platforms-filtered/expected-snaps.txt b/tests/spread/core24/remote-build/snaps/platforms-filtered/expected-snaps.txt new file mode 100644 index 0000000000..95f57c66a3 --- /dev/null +++ b/tests/spread/core24/remote-build/snaps/platforms-filtered/expected-snaps.txt @@ -0,0 +1 @@ +test-snap-platforms-filtered-core24_1.0_amd64.snap diff --git a/tests/spread/core24/remote-build/snaps/platforms-filtered/snapcraft.yaml b/tests/spread/core24/remote-build/snaps/platforms-filtered/snapcraft.yaml new file mode 100644 index 0000000000..722045069a --- /dev/null +++ b/tests/spread/core24/remote-build/snaps/platforms-filtered/snapcraft.yaml @@ -0,0 +1,20 @@ +name: test-snap-platforms-filtered-core24 +base: core24 +version: "1.0" +summary: Test snap for remote build +description: Test snap for remote build + +grade: stable +confinement: strict + +platforms: + amd64: + build-on: [amd64] + build-for: [amd64] + riscv64: + build-on: [riscv64] + build-for: [riscv64] + +parts: + my-part: + plugin: nil diff --git a/tests/spread/core24/remote-build/task.yaml b/tests/spread/core24/remote-build/task.yaml index 152d3abec4..483a168f42 100644 --- a/tests/spread/core24/remote-build/task.yaml +++ b/tests/spread/core24/remote-build/task.yaml @@ -12,6 +12,7 @@ environment: SNAP/platforms: platforms SNAP/no_platforms: no-platforms SNAP/platform_arg: platform-arg + SNAP/platforms_filtered: platforms-filtered SNAP/build_for_arg: build-for-arg CREDENTIALS_FILE: "$HOME/.local/share/snapcraft/launchpad-credentials" CREDENTIALS_FILE/new_credentials: "$HOME/.local/share/snapcraft/launchpad-credentials" @@ -33,13 +34,16 @@ prepare: | # set up launchpad token mkdir -p "$(dirname "$CREDENTIALS_FILE")" - echo -e "$LAUNCHPAD_TOKEN" >> "$CREDENTIALS_FILE" + echo -e "$LAUNCHPAD_TOKEN" > "$CREDENTIALS_FILE" restore: | cd "./snaps/$SNAP" - rm -f ./*.snap ./*.txt - rm -rf snap .git + # remove snaps and log files + rm -f ./*.snap ./snapcraft-*.txt + + # remove the temporary git repository + rm -rf .git execute: | cd "./snaps/$SNAP" diff --git a/tests/unit/commands/test_remote.py b/tests/unit/commands/test_remote.py index 0535031bd0..45ed63ffe6 100644 --- a/tests/unit/commands/test_remote.py +++ b/tests/unit/commands/test_remote.py @@ -618,14 +618,54 @@ def test_build_for_argument( mock_start_builds.assert_called_once_with(ANY, architectures=expected_build_fors) -def test_architecture_defined_twice_error( +@pytest.mark.parametrize( + ("archs", "expected_archs"), + [ + ("amd64", ["amd64"]), + ("riscv64", ["riscv64"]), + ("amd64,riscv64", ["amd64", "riscv64"]), + ], +) +def test_architectures_filter( + mocker, + snapcraft_yaml, + fake_services, + mock_confirm, + mock_remote_builder_fake_build_process, + archs, + expected_archs, +): + """Filter an 'architectures' key with '--build-for'.""" + snapcraft_yaml_dict = { + "base": "core22", + "architectures": [ + {"build-on": ["amd64"], "build-for": ["amd64"]}, + {"build-on": ["riscv64"], "build-for": ["riscv64"]}, + ], + } + snapcraft_yaml(**snapcraft_yaml_dict) + mocker.patch.object( + sys, + "argv", + ["snapcraft", "remote-build", "--build-for", archs], + ) + mock_start_builds = mocker.patch( + "craft_application.services.remotebuild.RemoteBuildService.start_builds" + ) + app = application.create_app() + app.run() + + mock_start_builds.assert_called_once_with(ANY, architectures=expected_archs) + + +def test_architectures_filter_error( capsys, mocker, snapcraft_yaml, fake_services, mock_confirm, ): - """Error if architectures are in the project metadata and as a build argument.""" + """Error if '--build-for' entirely filters the build plan.""" snapcraft_yaml_dict = { "base": "core22", "architectures": [{"build-on": ["riscv64"], "build-for": ["riscv64"]}], @@ -634,35 +674,72 @@ def test_architecture_defined_twice_error( mocker.patch.object( sys, "argv", - ["snapcraft", "remote-build", "--build-for", "riscv64"], + ["snapcraft", "remote-build", "--build-for", "arm64"], ) app = application.create_app() app.run() _, err = capsys.readouterr() + assert "No build matches the current execution environment." in err assert ( - "'--build-for' cannot be used when 'architectures' is in the snapcraft.yaml." - ) in err - assert ( - "Remove '--build-for' from the command line or remove 'architectures' in the snapcraft.yaml." + "Check the project's 'platforms' declaration, and the " + "'--platform' and '--build-for' parameters." ) in err -@pytest.mark.parametrize("base", const.CURRENT_BASES - {"core22", "devel"}) -@pytest.mark.parametrize("argument", ["--build-for", "--platform"]) -def test_platform_defined_twice_error( - base, - argument, +@pytest.mark.parametrize("arg", ["--build-for", "--platform"]) +@pytest.mark.parametrize( + ("archs", "expected_archs"), + [ + ("amd64", ["amd64"]), + ("riscv64", ["riscv64"]), + ("amd64,riscv64", ["amd64", "riscv64"]), + ], +) +def test_platforms_filter( + mocker, + snapcraft_yaml, + fake_services, + mock_confirm, + mock_remote_builder_fake_build_process, + arg, + archs, + expected_archs, +): + """Filter a 'platforms' key with '--build-for' or '--platform'.""" + snapcraft_yaml_dict = { + "base": "core24", + "platforms": { + "amd64": {"build-on": "amd64", "build-for": "amd64"}, + "riscv64": {"build-on": "riscv64", "build-for": "riscv64"}, + }, + } + snapcraft_yaml(**snapcraft_yaml_dict) + mocker.patch.object( + sys, + "argv", + ["snapcraft", "remote-build", arg, archs], + ) + mock_start_builds = mocker.patch( + "craft_application.services.remotebuild.RemoteBuildService.start_builds" + ) + app = application.create_app() + app.run() + + mock_start_builds.assert_called_once_with(ANY, architectures=expected_archs) + + +def test_platforms_filter_error( capsys, mocker, snapcraft_yaml, fake_services, mock_confirm, ): - """Error if platforms are in the project metadata and as a build argument.""" + """Error if '--build-for' entirely filters the build plan.""" snapcraft_yaml_dict = { - "base": base, + "base": "core24", "platforms": { "riscv64": {"build-on": "riscv64", "build-for": "riscv64"}, }, @@ -671,18 +748,17 @@ def test_platform_defined_twice_error( mocker.patch.object( sys, "argv", - ["snapcraft", "remote-build", argument, "riscv64"], + ["snapcraft", "remote-build", "--build-for", "arm64"], ) app = application.create_app() app.run() _, err = capsys.readouterr() + assert "No build matches the current execution environment." in err assert ( - f"{argument!r} cannot be used when 'platforms' is in the snapcraft.yaml." - ) in err - assert ( - f"Remove {argument!r} from the command line or remove 'platforms' in the snapcraft.yaml." + "Check the project's 'platforms' declaration, and the " + "'--platform' and '--build-for' parameters." ) in err diff --git a/tests/unit/test_application.py b/tests/unit/test_application.py index ea86a2b518..96510664a3 100644 --- a/tests/unit/test_application.py +++ b/tests/unit/test_application.py @@ -21,6 +21,7 @@ import sys from textwrap import dedent +import craft_application.launchpad import craft_application.remote import craft_cli import craft_parts.plugins @@ -704,11 +705,18 @@ def test_store_key_error(mocker, capsys): ) -def test_remote_build_error(mocker, capsys): +@pytest.mark.parametrize( + "error_class", + [ + craft_application.remote.RemoteBuildError, + craft_application.launchpad.LaunchpadError, + ], +) +def test_remote_build_error(mocker, capsys, error_class): """Catch remote build errors and include a documentation link.""" mocker.patch( "snapcraft.application.Application._run_inner", - side_effect=craft_application.remote.RemoteBuildError(message="test-error"), + side_effect=error_class("test-error"), ) return_code = application.main() From 60a5f3ed190a19abfe0d973ddc6cfe0a6975d98d Mon Sep 17 00:00:00 2001 From: Callahan Kovacs Date: Fri, 24 Jan 2025 11:17:29 -0600 Subject: [PATCH 2/7] docs: clarify behavior Signed-off-by: Callahan Kovacs --- docs/explanation/remote-build.rst | 29 +++++++++++++++++++---------- snapcraft/commands/remote.py | 3 ++- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/docs/explanation/remote-build.rst b/docs/explanation/remote-build.rst index c41031cd9b..120b5da920 100644 --- a/docs/explanation/remote-build.rst +++ b/docs/explanation/remote-build.rst @@ -89,20 +89,29 @@ Current ``--platform`` and ``--build-for`` behave differently than they do for :ref:`lifecycle commands`. -If the project file contains a ``platforms`` or ``architectures`` key, then -``--platform`` or ``--build-for`` filter the build plan defined by that key. +Remote builds are useful for building snaps on different architectures. Due +to this, the semantics for the ``--platform`` and ``--build-for`` arguments are +more complex than when building a snap locally. + +These arguments operate in one of two different ways depending on the +project file, depending on the presence of a ``platforms`` or ``architectures`` +key in the project file. + +The first mode of operation is when the ``platforms`` or ``architectures`` +key is present in the project file. In this scenario, ``--build-for`` and +``--platform`` operate similar to how they do for lifecycle commands. +``--platforms`` filters by platform name and ``--build-for`` filters by the +``build-for`` key. The difference from their usage in lifecycle commands is that +they may be a comma-separated list which allowing multiple snaps to be built. For more information about build plans and filtering, see :ref:`Build plans `. -If the project file doesn't contain a ``platforms`` or ``architectures`` entry, -then ``--platform`` or ``--build-for`` define the architectures to build for. +The second mode of operation is when there isn't a ``platforms`` or +``architectures`` key in the project file. In this scenario, ``--platforms`` +or ``--build-for`` define the architectures to build for. -It the project file doesn't contain a ``platforms`` or ``architectures`` entry -and ``--platform`` or ``--build-for`` are not provided, Snapcraft will build -for the host system's architecture. - -These ``--platform`` and ``--build-for`` arguments are mutually exclusive and -must be a comma-separated list of debian architectures. +Similar to their usage in lifecycle comands, the ``--platform`` and +``--build-for`` arguments are mutually exclusive. ``core22`` snaps can only use ``--build-for``. ``core24`` and newer snaps can use ``--platform`` or ``--build-for``. diff --git a/snapcraft/commands/remote.py b/snapcraft/commands/remote.py index 3e96610ee3..cc3e8b803f 100644 --- a/snapcraft/commands/remote.py +++ b/snapcraft/commands/remote.py @@ -69,7 +69,8 @@ class RemoteBuildCommand(ExtensibleCommand): ``--build-for`` arguments. If there are no architectures defined in the project or as arguments, - then the default behavior is to build for the host architecture. + then the default behavior is to build for the host architecture of the + local machine. Interrupted remote builds can be resumed using the --recover option, followed by the build number informed when the remote From fb3c0219dca59c648eb4070dc0e9c5846f897e6a Mon Sep 17 00:00:00 2001 From: Callahan Kovacs Date: Fri, 24 Jan 2025 13:05:34 -0600 Subject: [PATCH 3/7] chore: drop --platform Signed-off-by: Callahan Kovacs --- docs/explanation/remote-build.rst | 41 +++--- snapcraft/commands/remote.py | 102 ++++---------- .../snaps/all/expected-snaps.txt | 2 +- .../snaps/all/snapcraft.yaml | 2 +- .../snaps/architectures/expected-snaps.txt | 2 - .../snaps/archs/expected-snaps.txt | 2 + .../{architectures => archs}/snapcraft.yaml | 2 +- .../snaps/no-architectures/expected-snaps.txt | 1 - .../snaps/no-archs/expected-snaps.txt | 1 + .../snapcraft.yaml | 2 +- .../core20/remote-build-legacy/task.yaml | 11 +- .../snaps/no-architectures/expected-snaps.txt | 2 +- .../snaps/no-architectures/snapcraft.yaml | 2 +- .../core22/remote-build-legacy/task.yaml | 7 +- .../remote-build/snaps/all/expected-snaps.txt | 2 +- .../remote-build/snaps/all/snapcraft.yaml | 2 +- .../architectures-filtered/arguments.txt | 1 - .../architectures-filtered/expected-snaps.txt | 1 - .../snaps/architectures/expected-snaps.txt | 2 - .../snaps/archs/expected-snaps.txt | 2 + .../{architectures => archs}/snapcraft.yaml | 2 +- .../snaps/build-for-arg/expected-snaps.txt | 2 - .../arguments.txt | 0 .../build-for-with-archs/expected-snaps.txt | 2 + .../snapcraft.yaml | 4 +- .../snaps/build-for}/arguments.txt | 0 .../snaps/build-for/expected-snaps.txt | 2 + .../snapcraft.yaml | 2 +- .../snaps/no-architectures/expected-snaps.txt | 1 - .../snaps/no-archs/expected-snaps.txt | 1 + .../snapcraft.yaml | 2 +- tests/spread/core22/remote-build/task.yaml | 18 ++- .../remote-build/snaps/all/expected-snaps.txt | 2 +- .../remote-build/snaps/all/snapcraft.yaml | 2 +- .../snaps/build-for-arg/expected-snaps.txt | 2 - .../snaps/build-for-arg/snapcraft.yaml | 12 -- .../build-for-with-platforms/arguments.txt | 1 + .../expected-snaps.txt | 2 + .../snapcraft.yaml | 5 +- .../snaps/build-for/arguments.txt | 1 + .../snaps/build-for/expected-snaps.txt | 2 + .../snapcraft.yaml | 2 +- .../snaps/no-platforms/expected-snaps.txt | 2 +- .../snaps/no-platforms/snapcraft.yaml | 2 +- .../snaps/platform-arg/arguments.txt | 1 - .../snaps/platform-arg/expected-snaps.txt | 2 - .../snaps/platforms-filtered/arguments.txt | 1 - .../platforms-filtered/expected-snaps.txt | 1 - .../snaps/platforms/expected-snaps.txt | 6 +- tests/spread/core24/remote-build/task.yaml | 5 +- tests/unit/commands/test_remote.py | 125 ++---------------- 51 files changed, 114 insertions(+), 287 deletions(-) delete mode 100644 tests/spread/core20/remote-build-legacy/snaps/architectures/expected-snaps.txt create mode 100644 tests/spread/core20/remote-build-legacy/snaps/archs/expected-snaps.txt rename tests/spread/core20/remote-build-legacy/snaps/{architectures => archs}/snapcraft.yaml (88%) delete mode 100644 tests/spread/core20/remote-build-legacy/snaps/no-architectures/expected-snaps.txt create mode 100644 tests/spread/core20/remote-build-legacy/snaps/no-archs/expected-snaps.txt rename tests/spread/core20/remote-build-legacy/snaps/{no-architectures => no-archs}/snapcraft.yaml (81%) delete mode 100644 tests/spread/core22/remote-build/snaps/architectures-filtered/arguments.txt delete mode 100644 tests/spread/core22/remote-build/snaps/architectures-filtered/expected-snaps.txt delete mode 100644 tests/spread/core22/remote-build/snaps/architectures/expected-snaps.txt create mode 100644 tests/spread/core22/remote-build/snaps/archs/expected-snaps.txt rename tests/spread/core22/remote-build/snaps/{architectures => archs}/snapcraft.yaml (88%) delete mode 100644 tests/spread/core22/remote-build/snaps/build-for-arg/expected-snaps.txt rename tests/spread/core22/remote-build/snaps/{build-for-arg => build-for-with-archs}/arguments.txt (100%) create mode 100644 tests/spread/core22/remote-build/snaps/build-for-with-archs/expected-snaps.txt rename tests/spread/core22/remote-build/snaps/{architectures-filtered => build-for-with-archs}/snapcraft.yaml (78%) rename tests/spread/{core24/remote-build/snaps/build-for-arg => core22/remote-build/snaps/build-for}/arguments.txt (100%) create mode 100644 tests/spread/core22/remote-build/snaps/build-for/expected-snaps.txt rename tests/spread/core22/remote-build/snaps/{build-for-arg => build-for}/snapcraft.yaml (82%) delete mode 100644 tests/spread/core22/remote-build/snaps/no-architectures/expected-snaps.txt create mode 100644 tests/spread/core22/remote-build/snaps/no-archs/expected-snaps.txt rename tests/spread/core22/remote-build/snaps/{no-architectures => no-archs}/snapcraft.yaml (81%) delete mode 100644 tests/spread/core24/remote-build/snaps/build-for-arg/expected-snaps.txt delete mode 100644 tests/spread/core24/remote-build/snaps/build-for-arg/snapcraft.yaml create mode 100644 tests/spread/core24/remote-build/snaps/build-for-with-platforms/arguments.txt create mode 100644 tests/spread/core24/remote-build/snaps/build-for-with-platforms/expected-snaps.txt rename tests/spread/core24/remote-build/snaps/{platforms-filtered => build-for-with-platforms}/snapcraft.yaml (76%) create mode 100644 tests/spread/core24/remote-build/snaps/build-for/arguments.txt create mode 100644 tests/spread/core24/remote-build/snaps/build-for/expected-snaps.txt rename tests/spread/core24/remote-build/snaps/{platform-arg => build-for}/snapcraft.yaml (82%) delete mode 100644 tests/spread/core24/remote-build/snaps/platform-arg/arguments.txt delete mode 100644 tests/spread/core24/remote-build/snaps/platform-arg/expected-snaps.txt delete mode 100644 tests/spread/core24/remote-build/snaps/platforms-filtered/arguments.txt delete mode 100644 tests/spread/core24/remote-build/snaps/platforms-filtered/expected-snaps.txt diff --git a/docs/explanation/remote-build.rst b/docs/explanation/remote-build.rst index 120b5da920..bf636bfe89 100644 --- a/docs/explanation/remote-build.rst +++ b/docs/explanation/remote-build.rst @@ -82,39 +82,30 @@ Remote builds can be orchestrated for multiple platforms and architectures. Current ^^^^^^^ -``--platform`` and ``--build-for`` -********************************** +``--build-for`` +*************** .. note:: - ``--platform`` and ``--build-for`` behave differently than they do for + ``--build-for`` behaves differently for ``remote-build`` than it does for :ref:`lifecycle commands`. Remote builds are useful for building snaps on different architectures. Due -to this, the semantics for the ``--platform`` and ``--build-for`` arguments are -more complex than when building a snap locally. +to this, the semantics for the ``--build-for`` argument is more complex than +when building a snap locally. -These arguments operate in one of two different ways depending on the -project file, depending on the presence of a ``platforms`` or ``architectures`` -key in the project file. +The argument operates in one of two different ways depending on the presence +of a ``platforms`` or ``architectures`` key in the project file. The first mode of operation is when the ``platforms`` or ``architectures`` -key is present in the project file. In this scenario, ``--build-for`` and -``--platform`` operate similar to how they do for lifecycle commands. -``--platforms`` filters by platform name and ``--build-for`` filters by the -``build-for`` key. The difference from their usage in lifecycle commands is that -they may be a comma-separated list which allowing multiple snaps to be built. -For more information about build plans and filtering, see -:ref:`Build plans `. +key is present in the project file. In this scenario, ``--build-for`` operates +similar to how it does for lifecycle commands. The difference from its usage in +lifecycle commands is that ``--build-for`` may be a comma-separated list, which +allows multiple snaps to be built. For more information about build plans and +filtering, see :ref:`Build plans `. The second mode of operation is when there isn't a ``platforms`` or -``architectures`` key in the project file. In this scenario, ``--platforms`` -or ``--build-for`` define the architectures to build for. - -Similar to their usage in lifecycle comands, the ``--platform`` and -``--build-for`` arguments are mutually exclusive. - -``core22`` snaps can only use ``--build-for``. ``core24`` and newer snaps -can use ``--platform`` or ``--build-for``. +``architectures`` key in the project file. In this scenario, ``--build-for`` +defines the architectures to build for. Project platforms and architectures *********************************** @@ -134,8 +125,8 @@ Snapcraft will request a build for each unique ``build-for`` architecture. ``build-on`` architecture (`[14]`_). If the project metadata does not contain a ``platforms`` or ``architectures`` -entry and no ``--build-for`` or ``--platform`` are passed, Snapcraft will -request a build on, and for, the host's architecture. +entry and ``--build-for`` is not provided, Snapcraft will request a build on, +and for, the host's architecture. The remote builder does not work for ``core20`` snaps because it cannot parse the ``run-on`` keyword in a ``core20`` architecture entry (`[2]`_). diff --git a/snapcraft/commands/remote.py b/snapcraft/commands/remote.py index cc3e8b803f..4ea4b54c31 100644 --- a/snapcraft/commands/remote.py +++ b/snapcraft/commands/remote.py @@ -62,15 +62,15 @@ class RemoteBuildCommand(ExtensibleCommand): If the project contains a ``platforms`` or ``architectures`` key, then project's build plan is used. The build plan can be filtered - using the ``--platform`` or ``--build-for`` arguments. + using the ``--build-for`` argument. If the project doesn't contain a ``platforms`` or ``architectures`` key, - then the architectures to build for are defined by the ``--platform`` or - ``--build-for`` arguments. + then the architectures to build for are defined by the ``--build-for`` + argument. - If there are no architectures defined in the project or as arguments, - then the default behavior is to build for the host architecture of the - local machine. + If there are no architectures defined in the project file or with + ``--build-for``, then the default behavior is to build for the host + architecture of the local machine. Interrupted remote builds can be resumed using the --recover option, followed by the build number informed when the remote @@ -110,18 +110,7 @@ def _fill_parser(self, parser: argparse.ArgumentParser) -> None: "--build-id", metavar="build-id", help="Specific build ID to retrieve" ) - group = parser.add_mutually_exclusive_group() - group.add_argument( - "--platform", - type=lambda arg: [arch.strip() for arch in arg.split(",")], - metavar="name", - default=os.getenv("CRAFT_PLATFORM"), - help="Comma-separated list of platforms to build for", - # '--platform' needs to be handled differently since remote-build can - # build for an architecture that is not in the project metadata - dest="remote_build_platforms", - ) - group.add_argument( + parser.add_argument( "--build-for", type=lambda arg: [arch.strip() for arch in arg.split(",")], metavar="arch", @@ -165,16 +154,17 @@ def _validate(self, parsed_args: argparse.Namespace) -> None: retcode=os.EX_NOPERM, ) - if ( - parsed_args.remote_build_platforms - and self.project.get_effective_base() == "core22" - ): - raise errors.RemoteBuildError( - "'--platform' cannot be used for core22 snaps.", - resolution="Use '--build-for' instead.", - doc_slug="/explanation/remote-build.html", - retcode=os.EX_CONFIG, - ) + for build_for in parsed_args.remote_build_build_fors or []: + if build_for not in [*SUPPORTED_ARCHS, "all"]: + raise errors.RemoteBuildError( + f"Unsupported build-for architecture {build_for!r}.", + resolution=( + "Use a supported debian architecture. Supported " + f"architectures are: {humanize_list(SUPPORTED_ARCHS, 'and')}" + ), + doc_slug="/explanation/remote-build.html", + retcode=os.EX_CONFIG, + ) self._validate_single_artifact_per_build_on() @@ -246,10 +236,7 @@ def _run( # noqa: PLR0915 [too-many-statements] emit.trace(f"Project directory: {project_dir}") self._validate(parsed_args) - archs = self._get_archs( - build_fors=parsed_args.remote_build_build_fors, - platforms=parsed_args.remote_build_platforms, - ) + archs = self._get_archs(parsed_args.remote_build_build_fors) if parsed_args.launchpad_timeout: emit.debug(f"Setting timeout to {parsed_args.launchpad_timeout} seconds") @@ -373,22 +360,20 @@ def _monitor_and_complete( # noqa: PLR0912, PLR0915 ) return return_code - def _get_archs(self, build_fors: list[str], platforms: list[str]) -> list[str]: + def _get_archs(self, build_fors: list[str]) -> list[str]: """Get the architectures to build for. If the project contains a ``platforms`` or ``architectures`` key, then project's build plan is used to determine the architectures to build for. The build plan - can be filtered using the ``--platform`` or ``--build-for`` arguments. + can be filtered using the ``--build-for`` argument. If the project doesn't contain a ``platforms`` or ``architectures`` key, then - the architectures to build for are defined by the ``--platform`` or - ``--build-for`` arguments. + the architectures to build for are defined by the ``--build-for`` argument. If there are no architectures defined in the project or as arguments, then the default behavior is to build for the host architecture. :param build_fors: A list of build-for entries. - :param platforms: A list of platforms. :raises EmptyBuildPlanError: If the build plan is filtered to an empty list. :raises RemoteBuildError: If an unsupported architecture is provided. @@ -396,10 +381,8 @@ def _get_archs(self, build_fors: list[str], platforms: list[str]) -> list[str]: :returns: A list of architectures. """ archs: list[str] = [] - # core22 projects with an `architectures` key will have a corresponding `platforms` - # key when the project is unmarshalled if self.project.platforms or self.project._architectures_in_yaml: - # if the project has platforms, then the `--platforms` and `--build-for` arguments act as filters + # if the project has platforms, then `--build-for` acts as a filter if build_fors: emit.debug("Filtering the build plan using the '--build-for' argument.") for build_for in build_fors: @@ -412,31 +395,14 @@ def _get_archs(self, build_fors: list[str], platforms: list[str]) -> list[str]: archs.extend([info.build_for for info in filtered_build_plan]) if not archs: raise craft_application.errors.EmptyBuildPlanError() - elif platforms: - emit.debug("Filtering the build plan using the '--platforms' argument.") - for platform in platforms: - filtered_build_plan = filter_plan( - self.build_plan, - platform=platform, - build_for=None, - host_arch=None, - ) - archs.extend([info.build_for for info in filtered_build_plan]) - if not archs: - raise craft_application.errors.EmptyBuildPlanError() else: emit.debug("Using the project's build plan") archs = [build_info.build_for for build_info in self.build_plan] - # No platforms in the project means '--build-for' and '--platforms' no longer act as filters. - # Instead, they define the architectures to build for. + # No architectures in the project means '--build-for' no longer acts as a filter. + # Instead, it defines the architectures to build for. elif build_fors: emit.debug("Using '--build-for' as the list of architectures to build for") - _validate_archs(build_fors, "build-for architecture") archs = build_fors - elif platforms: - emit.debug("Using '--platforms' as the list of architectures to build for") - _validate_archs(platforms, "platform") - archs = platforms # default is to build for the host architecture else: archs = [str(DebianArchitecture.from_host())] @@ -447,21 +413,3 @@ def _get_archs(self, build_fors: list[str], platforms: list[str]) -> list[str]: emit.debug(f"Architectures to build for: {humanize_list(archs, 'and')}") return archs - - -def _validate_archs(archs: list[str], key_name: str) -> None: - """Validate that a list of architectures are valid. - - :raises RemoteBuildError: If an unsupported architecture is provided. - """ - for arch in archs: - if arch not in SUPPORTED_ARCHS: - raise errors.RemoteBuildError( - f"Unsupported {key_name} {arch!r}.", - resolution=( - "Use a supported debian architecture. Supported " - f"architectures are: {humanize_list(SUPPORTED_ARCHS, 'and')}" - ), - doc_slug="/explanation/remote-build.html", - retcode=os.EX_CONFIG, - ) diff --git a/tests/spread/core20/remote-build-legacy/snaps/all/expected-snaps.txt b/tests/spread/core20/remote-build-legacy/snaps/all/expected-snaps.txt index ff22b906ff..0e0604c25e 100644 --- a/tests/spread/core20/remote-build-legacy/snaps/all/expected-snaps.txt +++ b/tests/spread/core20/remote-build-legacy/snaps/all/expected-snaps.txt @@ -1 +1 @@ -test-snap-all-core20_1.0_all.snap +all-core20_1.0_all.snap diff --git a/tests/spread/core20/remote-build-legacy/snaps/all/snapcraft.yaml b/tests/spread/core20/remote-build-legacy/snaps/all/snapcraft.yaml index f27e56855c..d64d597f06 100644 --- a/tests/spread/core20/remote-build-legacy/snaps/all/snapcraft.yaml +++ b/tests/spread/core20/remote-build-legacy/snaps/all/snapcraft.yaml @@ -1,4 +1,4 @@ -name: test-snap-all-core20 +name: all-core20 base: core20 version: "1.0" summary: Test snap for remote build diff --git a/tests/spread/core20/remote-build-legacy/snaps/architectures/expected-snaps.txt b/tests/spread/core20/remote-build-legacy/snaps/architectures/expected-snaps.txt deleted file mode 100644 index 51a82ced03..0000000000 --- a/tests/spread/core20/remote-build-legacy/snaps/architectures/expected-snaps.txt +++ /dev/null @@ -1,2 +0,0 @@ -test-snap-architectures-core20_1.0_amd64.snap -test-snap-architectures-core20_1.0_arm64.snap diff --git a/tests/spread/core20/remote-build-legacy/snaps/archs/expected-snaps.txt b/tests/spread/core20/remote-build-legacy/snaps/archs/expected-snaps.txt new file mode 100644 index 0000000000..6da419cabc --- /dev/null +++ b/tests/spread/core20/remote-build-legacy/snaps/archs/expected-snaps.txt @@ -0,0 +1,2 @@ +archs-core20_1.0_amd64.snap +archs-core20_1.0_arm64.snap diff --git a/tests/spread/core20/remote-build-legacy/snaps/architectures/snapcraft.yaml b/tests/spread/core20/remote-build-legacy/snaps/archs/snapcraft.yaml similarity index 88% rename from tests/spread/core20/remote-build-legacy/snaps/architectures/snapcraft.yaml rename to tests/spread/core20/remote-build-legacy/snaps/archs/snapcraft.yaml index 7fa5d6d774..1a3bc7903b 100644 --- a/tests/spread/core20/remote-build-legacy/snaps/architectures/snapcraft.yaml +++ b/tests/spread/core20/remote-build-legacy/snaps/archs/snapcraft.yaml @@ -1,4 +1,4 @@ -name: test-snap-architectures-core20 +name: archs-core20 base: core20 version: "1.0" summary: Test snap for remote build diff --git a/tests/spread/core20/remote-build-legacy/snaps/no-architectures/expected-snaps.txt b/tests/spread/core20/remote-build-legacy/snaps/no-architectures/expected-snaps.txt deleted file mode 100644 index 482e43987c..0000000000 --- a/tests/spread/core20/remote-build-legacy/snaps/no-architectures/expected-snaps.txt +++ /dev/null @@ -1 +0,0 @@ -test-snap-no-architectures-core20_1.0_amd64.snap diff --git a/tests/spread/core20/remote-build-legacy/snaps/no-archs/expected-snaps.txt b/tests/spread/core20/remote-build-legacy/snaps/no-archs/expected-snaps.txt new file mode 100644 index 0000000000..1af01c437f --- /dev/null +++ b/tests/spread/core20/remote-build-legacy/snaps/no-archs/expected-snaps.txt @@ -0,0 +1 @@ +no-archs-core20_1.0_amd64.snap diff --git a/tests/spread/core20/remote-build-legacy/snaps/no-architectures/snapcraft.yaml b/tests/spread/core20/remote-build-legacy/snaps/no-archs/snapcraft.yaml similarity index 81% rename from tests/spread/core20/remote-build-legacy/snaps/no-architectures/snapcraft.yaml rename to tests/spread/core20/remote-build-legacy/snaps/no-archs/snapcraft.yaml index d80b302735..a2d18d0ff3 100644 --- a/tests/spread/core20/remote-build-legacy/snaps/no-architectures/snapcraft.yaml +++ b/tests/spread/core20/remote-build-legacy/snaps/no-archs/snapcraft.yaml @@ -1,4 +1,4 @@ -name: test-snap-no-architectures-core20 +name: no-archs-core20 base: core20 version: "1.0" summary: Test snap for remote build diff --git a/tests/spread/core20/remote-build-legacy/task.yaml b/tests/spread/core20/remote-build-legacy/task.yaml index 997b28f3af..1062740bf3 100644 --- a/tests/spread/core20/remote-build-legacy/task.yaml +++ b/tests/spread/core20/remote-build-legacy/task.yaml @@ -4,10 +4,10 @@ kill-timeout: 180m environment: LAUNCHPAD_TOKEN: "$(HOST: echo ${LAUNCHPAD_TOKEN})" - SNAP: no-architectures + SNAP: no-archs SNAP/all: all - SNAP/no_architectures: no-architectures - SNAP/architectures: architectures + SNAP/no_archs: no-archs + SNAP/archs: archs SNAPCRAFT_REMOTE_BUILD_STRATEGY: force-fallback CREDENTIALS_FILE: "$HOME/.local/share/snapcraft/launchpad-credentials" CREDENTIALS_FILE/new_credentials: "$HOME/.local/share/snapcraft/launchpad-credentials" @@ -29,12 +29,13 @@ prepare: | # set up launchpad token mkdir -p "$(dirname "$CREDENTIALS_FILE")" - echo -e "$LAUNCHPAD_TOKEN" >> "$CREDENTIALS_FILE" + echo -e "$LAUNCHPAD_TOKEN" > "$CREDENTIALS_FILE" restore: | cd "./snaps/$SNAP" - rm -f ./*.snap ./*.txt + # remove snaps and log files + rm -f ./*.snap ./snapcraft-*.txt execute: | cd "./snaps/$SNAP" diff --git a/tests/spread/core22/remote-build-legacy/snaps/no-architectures/expected-snaps.txt b/tests/spread/core22/remote-build-legacy/snaps/no-architectures/expected-snaps.txt index 2388cf27aa..a01a99749e 100644 --- a/tests/spread/core22/remote-build-legacy/snaps/no-architectures/expected-snaps.txt +++ b/tests/spread/core22/remote-build-legacy/snaps/no-architectures/expected-snaps.txt @@ -1 +1 @@ -test-snap-no-architectures-core22_1.0_amd64.snap +no-archs-core22_1.0_amd64.snap diff --git a/tests/spread/core22/remote-build-legacy/snaps/no-architectures/snapcraft.yaml b/tests/spread/core22/remote-build-legacy/snaps/no-architectures/snapcraft.yaml index ade4c76d0f..24c8d5c70e 100644 --- a/tests/spread/core22/remote-build-legacy/snaps/no-architectures/snapcraft.yaml +++ b/tests/spread/core22/remote-build-legacy/snaps/no-architectures/snapcraft.yaml @@ -1,4 +1,4 @@ -name: test-snap-no-architectures-core22 +name: no-archs-core22 base: core22 version: "1.0" summary: Test snap for remote build diff --git a/tests/spread/core22/remote-build-legacy/task.yaml b/tests/spread/core22/remote-build-legacy/task.yaml index 496dfb7deb..4f0842acd3 100644 --- a/tests/spread/core22/remote-build-legacy/task.yaml +++ b/tests/spread/core22/remote-build-legacy/task.yaml @@ -4,7 +4,7 @@ kill-timeout: 180m environment: LAUNCHPAD_TOKEN: "$(HOST: echo ${LAUNCHPAD_TOKEN})" - SNAP: no-architectures + SNAP: no-archs SNAPCRAFT_REMOTE_BUILD_STRATEGY: force-fallback CREDENTIALS_FILE: "$HOME/.local/share/snapcraft/launchpad-credentials" CREDENTIALS_FILE/new_credentials: "$HOME/.local/share/snapcraft/launchpad-credentials" @@ -20,12 +20,13 @@ prepare: | # set up launchpad token mkdir -p "$(dirname "$CREDENTIALS_FILE")" - echo -e "$LAUNCHPAD_TOKEN" >> "$CREDENTIALS_FILE" + echo -e "$LAUNCHPAD_TOKEN" > "$CREDENTIALS_FILE" restore: | cd "./snaps/$SNAP" - rm -f ./*.snap ./*.txt + # remove snaps and log files + rm -f ./*.snap ./snapcraft-*.txt execute: | cd "./snaps/$SNAP" diff --git a/tests/spread/core22/remote-build/snaps/all/expected-snaps.txt b/tests/spread/core22/remote-build/snaps/all/expected-snaps.txt index c744da54f0..2e731f477f 100644 --- a/tests/spread/core22/remote-build/snaps/all/expected-snaps.txt +++ b/tests/spread/core22/remote-build/snaps/all/expected-snaps.txt @@ -1 +1 @@ -test-snap-all-core22_1.0_all.snap +all-core22_1.0_all.snap diff --git a/tests/spread/core22/remote-build/snaps/all/snapcraft.yaml b/tests/spread/core22/remote-build/snaps/all/snapcraft.yaml index 8d6d872be8..31c62ab6f9 100644 --- a/tests/spread/core22/remote-build/snaps/all/snapcraft.yaml +++ b/tests/spread/core22/remote-build/snaps/all/snapcraft.yaml @@ -1,4 +1,4 @@ -name: test-snap-all-core22 +name: all-core22 base: core22 version: "1.0" summary: Test snap for remote build diff --git a/tests/spread/core22/remote-build/snaps/architectures-filtered/arguments.txt b/tests/spread/core22/remote-build/snaps/architectures-filtered/arguments.txt deleted file mode 100644 index 2bbc7b956e..0000000000 --- a/tests/spread/core22/remote-build/snaps/architectures-filtered/arguments.txt +++ /dev/null @@ -1 +0,0 @@ ---build-for amd64 diff --git a/tests/spread/core22/remote-build/snaps/architectures-filtered/expected-snaps.txt b/tests/spread/core22/remote-build/snaps/architectures-filtered/expected-snaps.txt deleted file mode 100644 index 24a021e27a..0000000000 --- a/tests/spread/core22/remote-build/snaps/architectures-filtered/expected-snaps.txt +++ /dev/null @@ -1 +0,0 @@ -test-snap-architectures-filtered-core22_1.0_amd64.snap diff --git a/tests/spread/core22/remote-build/snaps/architectures/expected-snaps.txt b/tests/spread/core22/remote-build/snaps/architectures/expected-snaps.txt deleted file mode 100644 index fe99de9213..0000000000 --- a/tests/spread/core22/remote-build/snaps/architectures/expected-snaps.txt +++ /dev/null @@ -1,2 +0,0 @@ -test-snap-architectures-core22_1.0_amd64.snap -test-snap-architectures-core22_1.0_arm64.snap diff --git a/tests/spread/core22/remote-build/snaps/archs/expected-snaps.txt b/tests/spread/core22/remote-build/snaps/archs/expected-snaps.txt new file mode 100644 index 0000000000..7a41b25956 --- /dev/null +++ b/tests/spread/core22/remote-build/snaps/archs/expected-snaps.txt @@ -0,0 +1,2 @@ +archs-core22_1.0_amd64.snap +archs-core22_1.0_arm64.snap diff --git a/tests/spread/core22/remote-build/snaps/architectures/snapcraft.yaml b/tests/spread/core22/remote-build/snaps/archs/snapcraft.yaml similarity index 88% rename from tests/spread/core22/remote-build/snaps/architectures/snapcraft.yaml rename to tests/spread/core22/remote-build/snaps/archs/snapcraft.yaml index 947152e967..0cac035bdc 100644 --- a/tests/spread/core22/remote-build/snaps/architectures/snapcraft.yaml +++ b/tests/spread/core22/remote-build/snaps/archs/snapcraft.yaml @@ -1,4 +1,4 @@ -name: test-snap-architectures-core22 +name: archs-core22 base: core22 version: "1.0" summary: Test snap for remote build diff --git a/tests/spread/core22/remote-build/snaps/build-for-arg/expected-snaps.txt b/tests/spread/core22/remote-build/snaps/build-for-arg/expected-snaps.txt deleted file mode 100644 index 5b9051821a..0000000000 --- a/tests/spread/core22/remote-build/snaps/build-for-arg/expected-snaps.txt +++ /dev/null @@ -1,2 +0,0 @@ -test-snap-build-for-arg-core22_1.0_amd64.snap -test-snap-build-for-arg-core22_1.0_s390x.snap diff --git a/tests/spread/core22/remote-build/snaps/build-for-arg/arguments.txt b/tests/spread/core22/remote-build/snaps/build-for-with-archs/arguments.txt similarity index 100% rename from tests/spread/core22/remote-build/snaps/build-for-arg/arguments.txt rename to tests/spread/core22/remote-build/snaps/build-for-with-archs/arguments.txt diff --git a/tests/spread/core22/remote-build/snaps/build-for-with-archs/expected-snaps.txt b/tests/spread/core22/remote-build/snaps/build-for-with-archs/expected-snaps.txt new file mode 100644 index 0000000000..3e6847266c --- /dev/null +++ b/tests/spread/core22/remote-build/snaps/build-for-with-archs/expected-snaps.txt @@ -0,0 +1,2 @@ +build-for-with-archs-core22_1.0_amd64.snap +build-for-with-archs-core22_1.0_s390x.snap diff --git a/tests/spread/core22/remote-build/snaps/architectures-filtered/snapcraft.yaml b/tests/spread/core22/remote-build/snaps/build-for-with-archs/snapcraft.yaml similarity index 78% rename from tests/spread/core22/remote-build/snaps/architectures-filtered/snapcraft.yaml rename to tests/spread/core22/remote-build/snaps/build-for-with-archs/snapcraft.yaml index d7b5d5a761..b38bf33998 100644 --- a/tests/spread/core22/remote-build/snaps/architectures-filtered/snapcraft.yaml +++ b/tests/spread/core22/remote-build/snaps/build-for-with-archs/snapcraft.yaml @@ -1,4 +1,4 @@ -name: test-snap-architectures-filtered-core22 +name: build-for-with-archs-core22 base: core22 version: "1.0" summary: Test snap for remote build @@ -10,6 +10,8 @@ confinement: strict architectures: - build-on: [amd64] build-for: [amd64] + - build-on: [s390x] + build-for: [s390x] - build-on: [riscv64] build-for: [riscv64] diff --git a/tests/spread/core24/remote-build/snaps/build-for-arg/arguments.txt b/tests/spread/core22/remote-build/snaps/build-for/arguments.txt similarity index 100% rename from tests/spread/core24/remote-build/snaps/build-for-arg/arguments.txt rename to tests/spread/core22/remote-build/snaps/build-for/arguments.txt diff --git a/tests/spread/core22/remote-build/snaps/build-for/expected-snaps.txt b/tests/spread/core22/remote-build/snaps/build-for/expected-snaps.txt new file mode 100644 index 0000000000..af7f1a0372 --- /dev/null +++ b/tests/spread/core22/remote-build/snaps/build-for/expected-snaps.txt @@ -0,0 +1,2 @@ +build-for-core22_1.0_amd64.snap +build-for-core22_1.0_s390x.snap diff --git a/tests/spread/core22/remote-build/snaps/build-for-arg/snapcraft.yaml b/tests/spread/core22/remote-build/snaps/build-for/snapcraft.yaml similarity index 82% rename from tests/spread/core22/remote-build/snaps/build-for-arg/snapcraft.yaml rename to tests/spread/core22/remote-build/snaps/build-for/snapcraft.yaml index 4dede42d0d..11c0c66cca 100644 --- a/tests/spread/core22/remote-build/snaps/build-for-arg/snapcraft.yaml +++ b/tests/spread/core22/remote-build/snaps/build-for/snapcraft.yaml @@ -1,4 +1,4 @@ -name: test-snap-build-for-arg-core22 +name: build-for-core22 base: core22 version: "1.0" summary: Test snap for remote build diff --git a/tests/spread/core22/remote-build/snaps/no-architectures/expected-snaps.txt b/tests/spread/core22/remote-build/snaps/no-architectures/expected-snaps.txt deleted file mode 100644 index 2388cf27aa..0000000000 --- a/tests/spread/core22/remote-build/snaps/no-architectures/expected-snaps.txt +++ /dev/null @@ -1 +0,0 @@ -test-snap-no-architectures-core22_1.0_amd64.snap diff --git a/tests/spread/core22/remote-build/snaps/no-archs/expected-snaps.txt b/tests/spread/core22/remote-build/snaps/no-archs/expected-snaps.txt new file mode 100644 index 0000000000..a01a99749e --- /dev/null +++ b/tests/spread/core22/remote-build/snaps/no-archs/expected-snaps.txt @@ -0,0 +1 @@ +no-archs-core22_1.0_amd64.snap diff --git a/tests/spread/core22/remote-build/snaps/no-architectures/snapcraft.yaml b/tests/spread/core22/remote-build/snaps/no-archs/snapcraft.yaml similarity index 81% rename from tests/spread/core22/remote-build/snaps/no-architectures/snapcraft.yaml rename to tests/spread/core22/remote-build/snaps/no-archs/snapcraft.yaml index ade4c76d0f..24c8d5c70e 100644 --- a/tests/spread/core22/remote-build/snaps/no-architectures/snapcraft.yaml +++ b/tests/spread/core22/remote-build/snaps/no-archs/snapcraft.yaml @@ -1,4 +1,4 @@ -name: test-snap-no-architectures-core22 +name: no-archs-core22 base: core22 version: "1.0" summary: Test snap for remote build diff --git a/tests/spread/core22/remote-build/task.yaml b/tests/spread/core22/remote-build/task.yaml index 3b2d9a08f2..5765d59925 100644 --- a/tests/spread/core22/remote-build/task.yaml +++ b/tests/spread/core22/remote-build/task.yaml @@ -4,12 +4,12 @@ kill-timeout: 180m environment: LAUNCHPAD_TOKEN: "$(HOST: echo ${LAUNCHPAD_TOKEN})" - SNAP: no-architectures + SNAP: no-archs SNAP/all: all - SNAP/no_architectures: no-architectures - SNAP/architectures: architectures - SNAP/architectures_filtered: architectures-filtered - SNAP/build_for_arg: build-for-arg + SNAP/no_archs: no-archs + SNAP/archs: archs + SNAP/build_for: build-for + SNAP/build_for_with_archs: build-for-with-archs SNAPCRAFT_REMOTE_BUILD_STRATEGY: disable-fallback CREDENTIALS_FILE: "$HOME/.local/share/snapcraft/launchpad-credentials" CREDENTIALS_FILE/new_credentials: "$HOME/.local/share/snapcraft/launchpad-credentials" @@ -31,12 +31,16 @@ prepare: | # set up launchpad token mkdir -p "$(dirname "$CREDENTIALS_FILE")" - echo -e "$LAUNCHPAD_TOKEN" >> "$CREDENTIALS_FILE" + echo -e "$LAUNCHPAD_TOKEN" > "$CREDENTIALS_FILE" restore: | cd "./snaps/$SNAP" - rm -f ./*.snap ./*.txt + # remove snaps and log files + rm -f ./*.snap ./snapcraft-*.txt + + # remove the temporary git repository + rm -rf .git execute: | cd "./snaps/$SNAP" diff --git a/tests/spread/core24/remote-build/snaps/all/expected-snaps.txt b/tests/spread/core24/remote-build/snaps/all/expected-snaps.txt index 851f79af8f..30675ea7fb 100644 --- a/tests/spread/core24/remote-build/snaps/all/expected-snaps.txt +++ b/tests/spread/core24/remote-build/snaps/all/expected-snaps.txt @@ -1 +1 @@ -test-snap-all-core24_1.0_all.snap +all-core24_1.0_all.snap diff --git a/tests/spread/core24/remote-build/snaps/all/snapcraft.yaml b/tests/spread/core24/remote-build/snaps/all/snapcraft.yaml index 2ff2511a3e..ce5b686f27 100644 --- a/tests/spread/core24/remote-build/snaps/all/snapcraft.yaml +++ b/tests/spread/core24/remote-build/snaps/all/snapcraft.yaml @@ -1,4 +1,4 @@ -name: test-snap-all-core24 +name: all-core24 base: core24 version: "1.0" summary: Test snap for remote build diff --git a/tests/spread/core24/remote-build/snaps/build-for-arg/expected-snaps.txt b/tests/spread/core24/remote-build/snaps/build-for-arg/expected-snaps.txt deleted file mode 100644 index ecd71f79c8..0000000000 --- a/tests/spread/core24/remote-build/snaps/build-for-arg/expected-snaps.txt +++ /dev/null @@ -1,2 +0,0 @@ -test-snap-build-for-arg-core24_1.0_amd64.snap -test-snap-build-for-arg-core24_1.0_s390x.snap diff --git a/tests/spread/core24/remote-build/snaps/build-for-arg/snapcraft.yaml b/tests/spread/core24/remote-build/snaps/build-for-arg/snapcraft.yaml deleted file mode 100644 index 1bafa9fbc4..0000000000 --- a/tests/spread/core24/remote-build/snaps/build-for-arg/snapcraft.yaml +++ /dev/null @@ -1,12 +0,0 @@ -name: test-snap-build-for-arg-core24 -base: core24 -version: "1.0" -summary: Test snap for remote build -description: Test snap for remote build - -grade: stable -confinement: strict - -parts: - my-part: - plugin: nil diff --git a/tests/spread/core24/remote-build/snaps/build-for-with-platforms/arguments.txt b/tests/spread/core24/remote-build/snaps/build-for-with-platforms/arguments.txt new file mode 100644 index 0000000000..c9eaf14f09 --- /dev/null +++ b/tests/spread/core24/remote-build/snaps/build-for-with-platforms/arguments.txt @@ -0,0 +1 @@ +--build-for amd64,s390x diff --git a/tests/spread/core24/remote-build/snaps/build-for-with-platforms/expected-snaps.txt b/tests/spread/core24/remote-build/snaps/build-for-with-platforms/expected-snaps.txt new file mode 100644 index 0000000000..b86312abb6 --- /dev/null +++ b/tests/spread/core24/remote-build/snaps/build-for-with-platforms/expected-snaps.txt @@ -0,0 +1,2 @@ +build-for-with-platforms-core24_1.0_amd64.snap +build-for-with-platforms-core24_1.0_s390x.snap diff --git a/tests/spread/core24/remote-build/snaps/platforms-filtered/snapcraft.yaml b/tests/spread/core24/remote-build/snaps/build-for-with-platforms/snapcraft.yaml similarity index 76% rename from tests/spread/core24/remote-build/snaps/platforms-filtered/snapcraft.yaml rename to tests/spread/core24/remote-build/snaps/build-for-with-platforms/snapcraft.yaml index 722045069a..b2e5b618bd 100644 --- a/tests/spread/core24/remote-build/snaps/platforms-filtered/snapcraft.yaml +++ b/tests/spread/core24/remote-build/snaps/build-for-with-platforms/snapcraft.yaml @@ -1,4 +1,4 @@ -name: test-snap-platforms-filtered-core24 +name: build-for-with-platforms-core24 base: core24 version: "1.0" summary: Test snap for remote build @@ -11,6 +11,9 @@ platforms: amd64: build-on: [amd64] build-for: [amd64] + s390x: + build-on: [s390x] + build-for: [s390x] riscv64: build-on: [riscv64] build-for: [riscv64] diff --git a/tests/spread/core24/remote-build/snaps/build-for/arguments.txt b/tests/spread/core24/remote-build/snaps/build-for/arguments.txt new file mode 100644 index 0000000000..c9eaf14f09 --- /dev/null +++ b/tests/spread/core24/remote-build/snaps/build-for/arguments.txt @@ -0,0 +1 @@ +--build-for amd64,s390x diff --git a/tests/spread/core24/remote-build/snaps/build-for/expected-snaps.txt b/tests/spread/core24/remote-build/snaps/build-for/expected-snaps.txt new file mode 100644 index 0000000000..71662211d4 --- /dev/null +++ b/tests/spread/core24/remote-build/snaps/build-for/expected-snaps.txt @@ -0,0 +1,2 @@ +build-for-core24_1.0_amd64.snap +build-for-core24_1.0_s390x.snap diff --git a/tests/spread/core24/remote-build/snaps/platform-arg/snapcraft.yaml b/tests/spread/core24/remote-build/snaps/build-for/snapcraft.yaml similarity index 82% rename from tests/spread/core24/remote-build/snaps/platform-arg/snapcraft.yaml rename to tests/spread/core24/remote-build/snaps/build-for/snapcraft.yaml index 7f793ff460..980030e78d 100644 --- a/tests/spread/core24/remote-build/snaps/platform-arg/snapcraft.yaml +++ b/tests/spread/core24/remote-build/snaps/build-for/snapcraft.yaml @@ -1,4 +1,4 @@ -name: test-snap-platform-arg-core24 +name: build-for-core24 base: core24 version: "1.0" summary: Test snap for remote build diff --git a/tests/spread/core24/remote-build/snaps/no-platforms/expected-snaps.txt b/tests/spread/core24/remote-build/snaps/no-platforms/expected-snaps.txt index bea51286d6..537298831a 100644 --- a/tests/spread/core24/remote-build/snaps/no-platforms/expected-snaps.txt +++ b/tests/spread/core24/remote-build/snaps/no-platforms/expected-snaps.txt @@ -1 +1 @@ -test-snap-no-platforms-core24_1.0_amd64.snap +no-platforms-core24_1.0_amd64.snap diff --git a/tests/spread/core24/remote-build/snaps/no-platforms/snapcraft.yaml b/tests/spread/core24/remote-build/snaps/no-platforms/snapcraft.yaml index 4cc212fa35..03f6718651 100644 --- a/tests/spread/core24/remote-build/snaps/no-platforms/snapcraft.yaml +++ b/tests/spread/core24/remote-build/snaps/no-platforms/snapcraft.yaml @@ -1,4 +1,4 @@ -name: test-snap-no-platforms-core24 +name: no-platforms-core24 base: core24 version: "1.0" summary: Test snap for remote build diff --git a/tests/spread/core24/remote-build/snaps/platform-arg/arguments.txt b/tests/spread/core24/remote-build/snaps/platform-arg/arguments.txt deleted file mode 100644 index dddd614311..0000000000 --- a/tests/spread/core24/remote-build/snaps/platform-arg/arguments.txt +++ /dev/null @@ -1 +0,0 @@ ---platform amd64,s390x diff --git a/tests/spread/core24/remote-build/snaps/platform-arg/expected-snaps.txt b/tests/spread/core24/remote-build/snaps/platform-arg/expected-snaps.txt deleted file mode 100644 index 1185b31b0c..0000000000 --- a/tests/spread/core24/remote-build/snaps/platform-arg/expected-snaps.txt +++ /dev/null @@ -1,2 +0,0 @@ -test-snap-platform-arg-core24_1.0_amd64.snap -test-snap-platform-arg-core24_1.0_s390x.snap diff --git a/tests/spread/core24/remote-build/snaps/platforms-filtered/arguments.txt b/tests/spread/core24/remote-build/snaps/platforms-filtered/arguments.txt deleted file mode 100644 index c2bfcf76fd..0000000000 --- a/tests/spread/core24/remote-build/snaps/platforms-filtered/arguments.txt +++ /dev/null @@ -1 +0,0 @@ ---platform amd64 diff --git a/tests/spread/core24/remote-build/snaps/platforms-filtered/expected-snaps.txt b/tests/spread/core24/remote-build/snaps/platforms-filtered/expected-snaps.txt deleted file mode 100644 index 95f57c66a3..0000000000 --- a/tests/spread/core24/remote-build/snaps/platforms-filtered/expected-snaps.txt +++ /dev/null @@ -1 +0,0 @@ -test-snap-platforms-filtered-core24_1.0_amd64.snap diff --git a/tests/spread/core24/remote-build/snaps/platforms/expected-snaps.txt b/tests/spread/core24/remote-build/snaps/platforms/expected-snaps.txt index 6106e568ff..3c041f2bfb 100644 --- a/tests/spread/core24/remote-build/snaps/platforms/expected-snaps.txt +++ b/tests/spread/core24/remote-build/snaps/platforms/expected-snaps.txt @@ -1,3 +1,3 @@ -test-snap-platforms-core24_1.0_amd64.snap -test-snap-platforms-core24_1.0_arm64.snap -test-snap-platforms-core24_1.0_armhf.snap +platforms-core24_1.0_amd64.snap +platforms-core24_1.0_arm64.snap +platforms-core24_1.0_armhf.snap diff --git a/tests/spread/core24/remote-build/task.yaml b/tests/spread/core24/remote-build/task.yaml index 483a168f42..3018b66797 100644 --- a/tests/spread/core24/remote-build/task.yaml +++ b/tests/spread/core24/remote-build/task.yaml @@ -11,9 +11,8 @@ environment: SNAP/all: all SNAP/platforms: platforms SNAP/no_platforms: no-platforms - SNAP/platform_arg: platform-arg - SNAP/platforms_filtered: platforms-filtered - SNAP/build_for_arg: build-for-arg + SNAP/build_for: build-for + SNAP/build_for_with_platforms: build-for-with-platforms CREDENTIALS_FILE: "$HOME/.local/share/snapcraft/launchpad-credentials" CREDENTIALS_FILE/new_credentials: "$HOME/.local/share/snapcraft/launchpad-credentials" CREDENTIALS_FILE/old_credentials: "$HOME/.local/share/snapcraft/provider/launchpad/credentials" diff --git a/tests/unit/commands/test_remote.py b/tests/unit/commands/test_remote.py index 45ed63ffe6..eb9a32c8ec 100644 --- a/tests/unit/commands/test_remote.py +++ b/tests/unit/commands/test_remote.py @@ -414,10 +414,12 @@ def test_default_architecture( ) +@pytest.mark.parametrize("args", [[], ["--build-for", "all"]]) @pytest.mark.parametrize("base", const.CURRENT_BASES - {"core22", "devel"}) def test_platform_build_for_all( mocker, snapcraft_yaml, + args, base, fake_services, mock_confirm, @@ -431,7 +433,7 @@ def test_platform_build_for_all( }, } snapcraft_yaml(**snapcraft_yaml_dict) - mocker.patch.object(sys, "argv", ["snapcraft", "remote-build"]) + mocker.patch.object(sys, "argv", ["snapcraft", "remote-build", *args]) mock_start_builds = mocker.patch( "craft_application.services.remotebuild.RemoteBuildService.start_builds" ) @@ -442,7 +444,9 @@ def test_platform_build_for_all( assert mock_start_builds.call_args[1]["architectures"] == ["all"] +@pytest.mark.parametrize("args", [[], ["--build-for", "all"]]) def test_platform_build_for_all_core22( + args, mocker, snapcraft_yaml, fake_services, @@ -457,7 +461,7 @@ def test_platform_build_for_all_core22( ], } snapcraft_yaml(**snapcraft_yaml_dict) - mocker.patch.object(sys, "argv", ["snapcraft", "remote-build"]) + mocker.patch.object(sys, "argv", ["snapcraft", "remote-build", *args]) mock_start_builds = mocker.patch( "craft_application.services.remotebuild.RemoteBuildService.start_builds" ) @@ -536,47 +540,6 @@ def test_architecture_in_project_metadata( ) -@pytest.mark.parametrize("base", const.CURRENT_BASES - {"core22", "devel"}) -@pytest.mark.parametrize( - ("platforms", "expected_platforms"), - [ - *zip(const.SnapArch, [[arch] for arch in const.SnapArch]), - ("amd64,riscv64", ["amd64", "riscv64"]), - ("amd64,riscv64,s390x", ["amd64", "riscv64", "s390x"]), - pytest.param(" amd64 , riscv64 ", ["amd64", "riscv64"], id="with-whitespace"), - pytest.param( - "amd64,amd64,riscv64", - ["amd64", "amd64", "riscv64"], - id="launchpad-handles-duplicates", - ), - ], -) -def test_platform_argument( - mocker, - snapcraft_yaml, - base, - fake_services, - mock_confirm, - mock_remote_builder_fake_build_process, - platforms, - expected_platforms, -): - """Use architectures provided by the `--platform` argument.""" - snapcraft_yaml(base=base) - mocker.patch.object( - sys, - "argv", - ["snapcraft", "remote-build", "--platform", platforms], - ) - mock_start_builds = mocker.patch( - "craft_application.services.remotebuild.RemoteBuildService.start_builds" - ) - app = application.create_app() - app.run() - - mock_start_builds.assert_called_once_with(ANY, architectures=expected_platforms) - - @pytest.mark.parametrize("base", const.CURRENT_BASES - {"devel"}) @pytest.mark.parametrize( ("build_fors", "expected_build_fors"), @@ -688,7 +651,6 @@ def test_architectures_filter_error( ) in err -@pytest.mark.parametrize("arg", ["--build-for", "--platform"]) @pytest.mark.parametrize( ("archs", "expected_archs"), [ @@ -703,11 +665,10 @@ def test_platforms_filter( fake_services, mock_confirm, mock_remote_builder_fake_build_process, - arg, archs, expected_archs, ): - """Filter a 'platforms' key with '--build-for' or '--platform'.""" + """Filter a 'platforms' key with '--build-for'.""" snapcraft_yaml_dict = { "base": "core24", "platforms": { @@ -719,7 +680,7 @@ def test_platforms_filter( mocker.patch.object( sys, "argv", - ["snapcraft", "remote-build", arg, archs], + ["snapcraft", "remote-build", "--build-for", archs], ) mock_start_builds = mocker.patch( "craft_application.services.remotebuild.RemoteBuildService.start_builds" @@ -762,49 +723,6 @@ def test_platforms_filter_error( ) in err -@pytest.mark.parametrize( - "platforms", - [ - "nonexistent", - "nonexistent,riscv64", - "riscv64,nonexistent", - "riscv64,nonexistent,amd64", - ], -) -@pytest.mark.parametrize("base", const.CURRENT_BASES - {"core22"}) -def test_unknown_platform_error( - capsys, - mocker, - snapcraft_yaml, - platforms, - base, - fake_services, - mock_confirm, -): - """Error if `--platform` is not a valid debian architecture.""" - snapcraft_yaml_dict = { - "base": base, - "build-base": "devel", - "grade": "devel", - } - snapcraft_yaml(**snapcraft_yaml_dict) - mocker.patch.object( - sys, - "argv", - ["snapcraft", "remote-build", "--platform", platforms], - ) - - app = application.create_app() - assert app.run() == os.EX_CONFIG - - _, err = capsys.readouterr() - assert "Unsupported platform 'nonexistent'" in err - assert ( - "Recommended resolution: Use a supported debian architecture. " - "Supported architectures are:" - ) in err - - @pytest.mark.parametrize( "build_fors", [ @@ -847,33 +765,6 @@ def test_unknown_build_for_error( ) in err -def test_platform_core22_error( - capsys, - mocker, - snapcraft_yaml, - fake_services, - mock_confirm, - mock_remote_builder_fake_build_process, -): - """Error on `--platform` for core22 snaps.""" - snapcraft_yaml(base="core22") - mocker.patch.object( - sys, - "argv", - ["snapcraft", "remote-build", "--platform", "amd64"], - ) - mocker.patch( - "craft_application.services.remotebuild.RemoteBuildService.start_builds" - ) - app = application.create_app() - assert app.run() == os.EX_CONFIG - - _, err = capsys.readouterr() - - assert "--platform' cannot be used for core22 snaps" in err - assert "Use '--build-for' instead." in err - - @pytest.mark.parametrize( ("base", "build_info", "error_messages"), [ From a96ed9cb881cd448dffb8f6c4a3409349adbfa67 Mon Sep 17 00:00:00 2001 From: Callahan Kovacs Date: Fri, 24 Jan 2025 13:18:14 -0600 Subject: [PATCH 4/7] chore: feedback from PR Signed-off-by: Callahan Kovacs --- snapcraft/commands/remote.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/snapcraft/commands/remote.py b/snapcraft/commands/remote.py index 4ea4b54c31..cccea0634e 100644 --- a/snapcraft/commands/remote.py +++ b/snapcraft/commands/remote.py @@ -61,7 +61,7 @@ class RemoteBuildCommand(ExtensibleCommand): local filesystem. If the project contains a ``platforms`` or ``architectures`` key, - then project's build plan is used. The build plan can be filtered + then the project's build plan is used. The build plan can be filtered using the ``--build-for`` argument. If the project doesn't contain a ``platforms`` or ``architectures`` key, @@ -371,7 +371,7 @@ def _get_archs(self, build_fors: list[str]) -> list[str]: the architectures to build for are defined by the ``--build-for`` argument. If there are no architectures defined in the project or as arguments, then the - default behavior is to build for the host architecture. + default behavior is to build for the host architecture of the local machine. :param build_fors: A list of build-for entries. From ee3ebdd2d3791e47985f586efcb485668c212a0c Mon Sep 17 00:00:00 2001 From: Callahan Kovacs Date: Fri, 24 Jan 2025 14:46:41 -0600 Subject: [PATCH 5/7] tests: update snap name Signed-off-by: Callahan Kovacs --- tests/spread/core24/remote-build/snaps/platforms/snapcraft.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/spread/core24/remote-build/snaps/platforms/snapcraft.yaml b/tests/spread/core24/remote-build/snaps/platforms/snapcraft.yaml index 2be885a16d..435656f1fc 100644 --- a/tests/spread/core24/remote-build/snaps/platforms/snapcraft.yaml +++ b/tests/spread/core24/remote-build/snaps/platforms/snapcraft.yaml @@ -1,4 +1,4 @@ -name: test-snap-platforms-core24 +name: platforms-core24 base: core24 version: "1.0" summary: Test snap for remote build From 8c1a2953df9f7988cae3b269ab8ae32628e610f3 Mon Sep 17 00:00:00 2001 From: Callahan Kovacs Date: Fri, 24 Jan 2025 15:50:13 -0600 Subject: [PATCH 6/7] tests: rename directory Signed-off-by: Callahan Kovacs --- .../snaps/{no-architectures => no-archs}/expected-snaps.txt | 0 .../snaps/{no-architectures => no-archs}/snapcraft.yaml | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename tests/spread/core22/remote-build-legacy/snaps/{no-architectures => no-archs}/expected-snaps.txt (100%) rename tests/spread/core22/remote-build-legacy/snaps/{no-architectures => no-archs}/snapcraft.yaml (100%) diff --git a/tests/spread/core22/remote-build-legacy/snaps/no-architectures/expected-snaps.txt b/tests/spread/core22/remote-build-legacy/snaps/no-archs/expected-snaps.txt similarity index 100% rename from tests/spread/core22/remote-build-legacy/snaps/no-architectures/expected-snaps.txt rename to tests/spread/core22/remote-build-legacy/snaps/no-archs/expected-snaps.txt diff --git a/tests/spread/core22/remote-build-legacy/snaps/no-architectures/snapcraft.yaml b/tests/spread/core22/remote-build-legacy/snaps/no-archs/snapcraft.yaml similarity index 100% rename from tests/spread/core22/remote-build-legacy/snaps/no-architectures/snapcraft.yaml rename to tests/spread/core22/remote-build-legacy/snaps/no-archs/snapcraft.yaml From eb2e9c880e57205bb941459b6b14fa3c9c5e1496 Mon Sep 17 00:00:00 2001 From: Callahan Kovacs Date: Fri, 24 Jan 2025 19:51:51 -0600 Subject: [PATCH 7/7] tests: unique hashes for spread tests Signed-off-by: Callahan Kovacs --- tests/spread/core20/remote-build-legacy/task.yaml | 8 ++++++-- tests/spread/core22/remote-build-legacy/task.yaml | 8 ++++++-- tests/spread/core22/remote-build/task.yaml | 8 ++++++-- tests/spread/core24/remote-build/task.yaml | 8 ++++++-- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/tests/spread/core20/remote-build-legacy/task.yaml b/tests/spread/core20/remote-build-legacy/task.yaml index 1062740bf3..f6aabf192a 100644 --- a/tests/spread/core20/remote-build-legacy/task.yaml +++ b/tests/spread/core20/remote-build-legacy/task.yaml @@ -31,11 +31,15 @@ prepare: | mkdir -p "$(dirname "$CREDENTIALS_FILE")" echo -e "$LAUNCHPAD_TOKEN" > "$CREDENTIALS_FILE" + # build ids are based on the project contents + # adding a date ensures each test has a unique build id + date > date.txt + restore: | cd "./snaps/$SNAP" - # remove snaps and log files - rm -f ./*.snap ./snapcraft-*.txt + # remove snaps, logs, and date files + rm -f ./*.snap ./snapcraft-*.txt ./date.txt execute: | cd "./snaps/$SNAP" diff --git a/tests/spread/core22/remote-build-legacy/task.yaml b/tests/spread/core22/remote-build-legacy/task.yaml index 4f0842acd3..a100d4b5cc 100644 --- a/tests/spread/core22/remote-build-legacy/task.yaml +++ b/tests/spread/core22/remote-build-legacy/task.yaml @@ -22,11 +22,15 @@ prepare: | mkdir -p "$(dirname "$CREDENTIALS_FILE")" echo -e "$LAUNCHPAD_TOKEN" > "$CREDENTIALS_FILE" + # build ids are based on the project contents + # adding a date ensures each test has a unique build id + date > date.txt + restore: | cd "./snaps/$SNAP" - # remove snaps and log files - rm -f ./*.snap ./snapcraft-*.txt + # remove snaps, logs, and date files + rm -f ./*.snap ./snapcraft-*.txt ./date.txt execute: | cd "./snaps/$SNAP" diff --git a/tests/spread/core22/remote-build/task.yaml b/tests/spread/core22/remote-build/task.yaml index 5765d59925..6283eb800b 100644 --- a/tests/spread/core22/remote-build/task.yaml +++ b/tests/spread/core22/remote-build/task.yaml @@ -33,11 +33,15 @@ prepare: | mkdir -p "$(dirname "$CREDENTIALS_FILE")" echo -e "$LAUNCHPAD_TOKEN" > "$CREDENTIALS_FILE" + # build ids are based on the project contents + # adding a date ensures each test has a unique build id + date > date.txt + restore: | cd "./snaps/$SNAP" - # remove snaps and log files - rm -f ./*.snap ./snapcraft-*.txt + # remove snaps, logs, and date files + rm -f ./*.snap ./snapcraft-*.txt ./date.txt # remove the temporary git repository rm -rf .git diff --git a/tests/spread/core24/remote-build/task.yaml b/tests/spread/core24/remote-build/task.yaml index 3018b66797..14bd5dfefd 100644 --- a/tests/spread/core24/remote-build/task.yaml +++ b/tests/spread/core24/remote-build/task.yaml @@ -35,11 +35,15 @@ prepare: | mkdir -p "$(dirname "$CREDENTIALS_FILE")" echo -e "$LAUNCHPAD_TOKEN" > "$CREDENTIALS_FILE" + # build ids are based on the project contents + # adding a date ensures each test has a unique build id + date > date.txt + restore: | cd "./snaps/$SNAP" - # remove snaps and log files - rm -f ./*.snap ./snapcraft-*.txt + # remove snaps, logs, and date files + rm -f ./*.snap ./snapcraft-*.txt ./date.txt # remove the temporary git repository rm -rf .git