From 782c60f0ba36c9f126a4ea9a9842ba4a585e6a1e Mon Sep 17 00:00:00 2001 From: Imani Pelton Date: Thu, 25 Jun 2026 11:45:24 -0400 Subject: [PATCH 1/4] fix(remote-build): ignore dangling symlinks --- craft_application/remote/worktree.py | 2 +- docs/reference/changelog.rst | 9 +++++++++ tests/unit/remote/test_worktree.py | 17 +++++++++++++++-- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/craft_application/remote/worktree.py b/craft_application/remote/worktree.py index 8576b271c..1ab28e6d6 100644 --- a/craft_application/remote/worktree.py +++ b/craft_application/remote/worktree.py @@ -51,7 +51,7 @@ def init_repo(self) -> None: if self._repo_dir.exists(): rmtree(self._repo_dir) - copytree(self._project_dir, self._repo_dir) + copytree(self._project_dir, self._repo_dir, ignore_dangling_symlinks=True) self._gitify_repository() diff --git a/docs/reference/changelog.rst b/docs/reference/changelog.rst index c4513d478..c1e9bf6ec 100644 --- a/docs/reference/changelog.rst +++ b/docs/reference/changelog.rst @@ -15,6 +15,15 @@ Changelog For a complete list of commits, check out the `1.2.3`_ release on GitHub. +7.0.1 (unreleased) +------------------ + +Bug fixes +========= + +- `remote-build` no longer raises an error when dangling symlinks are present in the + project repository + 7.0.0 (2026-06-02) ------------------ diff --git a/tests/unit/remote/test_worktree.py b/tests/unit/remote/test_worktree.py index d646a5bcb..ddb3a6413 100644 --- a/tests/unit/remote/test_worktree.py +++ b/tests/unit/remote/test_worktree.py @@ -38,7 +38,7 @@ def mock_base_directory(mocker, new_dir): return _mock_base_directory -@pytest.fixture(autouse=True) +@pytest.fixture def mock_copytree(mocker): """Returns a mocked `shutil.copytree()`.""" return mocker.patch("craft_application.remote.worktree.copytree") @@ -75,7 +75,7 @@ def test_worktree_init_clean_exception_wrapped(mock_git_repo): @pytest.mark.usefixtures("new_dir", "mock_copytree") def test_worktree_init_dirty(mock_base_directory, mock_git_repo): - """Test initialization of a WorkTree with a clean git repository.""" + """Test initialization of a WorkTree with a dirty git repository.""" mock_git_repo.return_value.is_clean.return_value = False worktree = WorkTree(app_name="test-app", build_id="test-id", project_dir=Path()) @@ -93,6 +93,19 @@ def test_worktree_init_dirty(mock_base_directory, mock_git_repo): ] +def test_worktree_init_dangling_symlinks(tmp_path: Path) -> None: + """Test that dangling symlinks don't break the repository init.""" + (tmp_path / "file").touch() + (tmp_path / "broken-link").symlink_to("not-real") + worktree = WorkTree(app_name="test-app", build_id="test-id", project_dir=tmp_path) + + worktree.init_repo() + + assert (tmp_path / "file").is_file() + # Broken symlinks are just ignored now + assert not (tmp_path / "broken-link").exists() + + @pytest.mark.usefixtures("new_dir") def test_worktree_repo_dir(): """Verify the `repo_dir` property.""" From be015200d242abb8c15eda2d6235c1286da06e6a Mon Sep 17 00:00:00 2001 From: Imani Pelton Date: Thu, 25 Jun 2026 11:48:51 -0400 Subject: [PATCH 2/4] test: oops, test the right directory --- tests/unit/remote/test_worktree.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/remote/test_worktree.py b/tests/unit/remote/test_worktree.py index ddb3a6413..6a11efab0 100644 --- a/tests/unit/remote/test_worktree.py +++ b/tests/unit/remote/test_worktree.py @@ -101,9 +101,9 @@ def test_worktree_init_dangling_symlinks(tmp_path: Path) -> None: worktree.init_repo() - assert (tmp_path / "file").is_file() + assert (worktree.repo_dir / "file").is_file() # Broken symlinks are just ignored now - assert not (tmp_path / "broken-link").exists() + assert not (worktree.repo_dir / "broken-link").exists() @pytest.mark.usefixtures("new_dir") From 8ee334650f35fabfcafc347b8c4d26534ff7b66c Mon Sep 17 00:00:00 2001 From: Imani Pelton Date: Thu, 25 Jun 2026 11:54:24 -0400 Subject: [PATCH 3/4] docs: fix changelog --- docs/reference/changelog.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/reference/changelog.rst b/docs/reference/changelog.rst index c1e9bf6ec..b83134830 100644 --- a/docs/reference/changelog.rst +++ b/docs/reference/changelog.rst @@ -21,8 +21,8 @@ Changelog Bug fixes ========= -- `remote-build` no longer raises an error when dangling symlinks are present in the - project repository +- ``remote-build`` no longer raises an error when dangling symlinks are present in the + project repository. 7.0.0 (2026-06-02) From 4fb32fbc7a491ba18e687c16e15330b35a123e8d Mon Sep 17 00:00:00 2001 From: Imani Pelton Date: Thu, 25 Jun 2026 13:02:14 -0400 Subject: [PATCH 4/4] test: the robot was right... --- tests/unit/remote/test_worktree.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/remote/test_worktree.py b/tests/unit/remote/test_worktree.py index 6a11efab0..4c3700f45 100644 --- a/tests/unit/remote/test_worktree.py +++ b/tests/unit/remote/test_worktree.py @@ -103,7 +103,7 @@ def test_worktree_init_dangling_symlinks(tmp_path: Path) -> None: assert (worktree.repo_dir / "file").is_file() # Broken symlinks are just ignored now - assert not (worktree.repo_dir / "broken-link").exists() + assert not (worktree.repo_dir / "broken-link").is_symlink() @pytest.mark.usefixtures("new_dir")