1these 2 derivations will be built:2 /nix/store/z8jljhp4waly7s65qad2ivmbsqgwhr91-python3-3.13.13-env.drv3 /nix/store/4i8pjvmjr95sq3cxqc4fnrlyz2n3dlcd-pytest-impure.drv4building '/nix/store/rk1g551dlhdg23nwqfg7yxcldak3fjcb-pytest-impure.drv'5pytest-impure> tribuchet: building on jamie6pytest-impure> ....FF...........FFFF.F [100%]7pytest-impure> =================================== FAILURES ===================================8pytest-impure> ___________________ TestFlakeService.test_update_flake_input ___________________9pytest-impure> 10pytest-impure> self = <update_flake_inputs.flake_service.FlakeService object at 0x7ffff661e3f0>11pytest-impure> input_name = 'flake-utils', flake_file = 'flake.nix'12pytest-impure> work_dir = '/build/tmpie236ebw'13pytest-impure> 14pytest-impure> def update_flake_input(15pytest-impure> self,16pytest-impure> input_name: str,17pytest-impure> flake_file: str,18pytest-impure> work_dir: str | None = None,19pytest-impure> ) -> None:20pytest-impure> """Update a specific flake input.21pytest-impure> 22pytest-impure> Args:23pytest-impure> input_name: Name of the input to update24pytest-impure> flake_file: Path to the flake file25pytest-impure> work_dir: Optional working directory to resolve flake file path from26pytest-impure> 27pytest-impure> """28pytest-impure> try:29pytest-impure> logger.info("Updating flake input: %s in %s", input_name, flake_file)30pytest-impure> 31pytest-impure> # If work_dir is provided, resolve the flake file relative to it32pytest-impure> absolute_flake_path = Path(work_dir) / flake_file if work_dir else Path(flake_file)33pytest-impure> 34pytest-impure> flake_dir = absolute_flake_path.parent or Path()35pytest-impure> absolute_flake_dir = flake_dir.resolve()36pytest-impure> 37pytest-impure> # Use a shallow URL because worktrees may not have the full history.38pytest-impure> # For subflakes, nix needs the URL to point to the git root39pytest-impure> # with a dir= parameter rather than the subdirectory directly.40pytest-impure> if work_dir:41pytest-impure> git_root = Path(work_dir).resolve()42pytest-impure> relative_dir = absolute_flake_dir.relative_to(git_root)43pytest-impure> flake_url = f"git+file://{git_root}?shallow=1"44pytest-impure> if str(relative_dir) != ".":45pytest-impure> flake_url += f"&dir={relative_dir}"46pytest-impure> else:47pytest-impure> flake_url = f"git+file://{absolute_flake_dir}?shallow=1"48pytest-impure> 49pytest-impure> > result = subprocess.run(50pytest-impure> [51pytest-impure> "nix",52pytest-impure> "flake",53pytest-impure> "update",54pytest-impure> "--flake",55pytest-impure> flake_url,56pytest-impure> input_name,57pytest-impure> ],58pytest-impure> cwd=str(flake_dir),59pytest-impure> capture_output=True,60pytest-impure> text=True,61pytest-impure> check=True,62pytest-impure> )63pytest-impure> 64pytest-impure> src/update_flake_inputs/flake_service.py:191: 65pytest-impure> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 66pytest-impure> 67pytest-impure> input = None, capture_output = True, timeout = None, check = True68pytest-impure> popenargs = (['nix', 'flake', 'update', '--flake', 'git+file:///build/tmpie236ebw?shallow=1', 'flake-utils'],)69pytest-impure> kwargs = {'cwd': '/build/tmpie236ebw', 'stderr': -1, 'stdout': -1, 'text': True}70pytest-impure> process = <Popen: returncode: 1 args: ['nix', 'flake', 'update', '--flake', 'git+file:...>71pytest-impure> stdout = ''72pytest-impure> stderr = "warning: you don't have Internet access; disabling some network-dependent features\nerror:\n … while updating t...b.com/repos/numtide/flake-utils/commits/HEAD': Could not resolve hostname (6) Could not resolve host: api.github.com\n"73pytest-impure> retcode = 174pytest-impure> 75pytest-impure> def run(*popenargs,76pytest-impure> input=None, capture_output=False, timeout=None, check=False, **kwargs):77pytest-impure> """Run command with arguments and return a CompletedProcess instance.78pytest-impure> 79pytest-impure> The returned instance will have attributes args, returncode, stdout and80pytest-impure> stderr. By default, stdout and stderr are not captured, and those attributes81pytest-impure> will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them,82pytest-impure> or pass capture_output=True to capture both.83pytest-impure> 84pytest-impure> If check is True and the exit code was non-zero, it raises a85pytest-impure> CalledProcessError. The CalledProcessError object will have the return code86pytest-impure> in the returncode attribute, and output & stderr attributes if those streams87pytest-impure> were captured.88pytest-impure> 89pytest-impure> If timeout (seconds) is given and the process takes too long,90pytest-impure> a TimeoutExpired exception will be raised.91pytest-impure> 92pytest-impure> There is an optional argument "input", allowing you to93pytest-impure> pass bytes or a string to the subprocess's stdin. If you use this argument94pytest-impure> you may not also use the Popen constructor's "stdin" argument, as95pytest-impure> it will be used internally.96pytest-impure> 97pytest-impure> By default, all communication is in bytes, and therefore any "input" should98pytest-impure> be bytes, and the stdout and stderr will be bytes. If in text mode, any99pytest-impure> "input" should be a string, and stdout and stderr will be strings decoded100pytest-impure> according to locale encoding, or by "encoding" if set. Text mode is101pytest-impure> triggered by setting any of text, encoding, errors or universal_newlines.102pytest-impure> 103pytest-impure> The other arguments are the same as for the Popen constructor.104pytest-impure> """105pytest-impure> if input is not None:106pytest-impure> if kwargs.get('stdin') is not None:107pytest-impure> raise ValueError('stdin and input arguments may not both be used.')108pytest-impure> kwargs['stdin'] = PIPE109pytest-impure> 110pytest-impure> if capture_output:111pytest-impure> if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None:112pytest-impure> raise ValueError('stdout and stderr arguments may not be used '113pytest-impure> 'with capture_output.')114pytest-impure> kwargs['stdout'] = PIPE115pytest-impure> kwargs['stderr'] = PIPE116pytest-impure> 117pytest-impure> with Popen(*popenargs, **kwargs) as process:118pytest-impure> try:119pytest-impure> stdout, stderr = process.communicate(input, timeout=timeout)120pytest-impure> except TimeoutExpired as exc:121pytest-impure> process.kill()122pytest-impure> if _mswindows:123pytest-impure> # Windows accumulates the output in a single blocking124pytest-impure> # read() call run on child threads, with the timeout125pytest-impure> # being done in a join() on those threads. communicate()126pytest-impure> # _after_ kill() is required to collect that and add it127pytest-impure> # to the exception.128pytest-impure> exc.stdout, exc.stderr = process.communicate()129pytest-impure> else:130pytest-impure> # POSIX _communicate already populated the output so131pytest-impure> # far into the TimeoutExpired exception.132pytest-impure> process.wait()133pytest-impure> raise134pytest-impure> except: # Including KeyboardInterrupt, communicate handled that.135pytest-impure> process.kill()136pytest-impure> # We don't call process.wait() as .__exit__ does that for us.137pytest-impure> raise138pytest-impure> retcode = process.poll()139pytest-impure> if check and retcode:140pytest-impure> > raise CalledProcessError(retcode, process.args,141pytest-impure> output=stdout, stderr=stderr)142pytest-impure> E subprocess.CalledProcessError: Command '['nix', 'flake', 'update', '--flake', 'git+file:///build/tmpie236ebw?shallow=1', 'flake-utils']' returned non-zero exit status 1.143pytest-impure> 144pytest-impure> /nix/store/6xbk6d4rk2dc9c3kbdx0rkvn2knfqcmp-python3-3.13.13-env/lib/python3.13/subprocess.py:577: CalledProcessError145pytest-impure> 146pytest-impure> The above exception was the direct cause of the following exception:147pytest-impure> 148pytest-impure> self = <tests.test_flake_service.TestFlakeService object at 0x7ffff6666c30>149pytest-impure> flake_service = <update_flake_inputs.flake_service.FlakeService object at 0x7ffff661e3f0>150pytest-impure> fixtures_path = PosixPath('/build/src/tests/fixtures')151pytest-impure> 152pytest-impure> @pytest.mark.impure153pytest-impure> def test_update_flake_input(154pytest-impure> self,155pytest-impure> flake_service: FlakeService,156pytest-impure> fixtures_path: Path,157pytest-impure> ) -> None:158pytest-impure> """Test updating a flake input and modifying the lock file."""159pytest-impure> # Create a temporary directory for the test160pytest-impure> with tempfile.TemporaryDirectory() as temp_dir:161pytest-impure> temp_path = Path(temp_dir)162pytest-impure> 163pytest-impure> # Copy minimal flake to temp directory164pytest-impure> shutil.copy(165pytest-impure> fixtures_path / "minimal" / "flake.nix",166pytest-impure> temp_path / "flake.nix",167pytest-impure> )168pytest-impure> shutil.copy(169pytest-impure> fixtures_path / "minimal" / "flake.lock",170pytest-impure> temp_path / "flake.lock",171pytest-impure> )172pytest-impure> 173pytest-impure> # Initialize git repo in temp directory174pytest-impure> subprocess.run(["git", "init"], cwd=temp_path, check=True)175pytest-impure> subprocess.run(["git", "add", "."], cwd=temp_path, check=True)176pytest-impure> subprocess.run(177pytest-impure> ["git", "commit", "-m", "Initial commit"],178pytest-impure> cwd=temp_path,179pytest-impure> check=True,180pytest-impure> env={181pytest-impure> **os.environ,182pytest-impure> "GIT_AUTHOR_NAME": "Test User",183pytest-impure> "GIT_AUTHOR_EMAIL": "test@example.com",184pytest-impure> "GIT_COMMITTER_NAME": "Test User",185pytest-impure> "GIT_COMMITTER_EMAIL": "test@example.com",186pytest-impure> },187pytest-impure> )188pytest-impure> 189pytest-impure> # Get the original lock file content190pytest-impure> original_lock_content = (temp_path / "flake.lock").read_text()191pytest-impure> original_lock = json.loads(original_lock_content)192pytest-impure> original_flake_utils_rev = original_lock["nodes"]["flake-utils"]["locked"]["rev"]193pytest-impure> 194pytest-impure> # Update flake-utils input195pytest-impure> > flake_service.update_flake_input("flake-utils", "flake.nix", str(temp_path))196pytest-impure> 197pytest-impure> tests/test_flake_service.py:198: 198pytest-impure> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 199pytest-impure> 200pytest-impure> self = <update_flake_inputs.flake_service.FlakeService object at 0x7ffff661e3f0>201pytest-impure> input_name = 'flake-utils', flake_file = 'flake.nix'202pytest-impure> work_dir = '/build/tmpie236ebw'203pytest-impure> 204pytest-impure> def update_flake_input(205pytest-impure> self,206pytest-impure> input_name: str,207pytest-impure> flake_file: str,208pytest-impure> work_dir: str | None = None,209pytest-impure> ) -> None:210pytest-impure> """Update a specific flake input.211pytest-impure> 212pytest-impure> Args:213pytest-impure> input_name: Name of the input to update214pytest-impure> flake_file: Path to the flake file215pytest-impure> work_dir: Optional working directory to resolve flake file path from216pytest-impure> 217pytest-impure> """218pytest-impure> try:219pytest-impure> logger.info("Updating flake input: %s in %s", input_name, flake_file)220pytest-impure> 221pytest-impure> # If work_dir is provided, resolve the flake file relative to it222pytest-impure> absolute_flake_path = Path(work_dir) / flake_file if work_dir else Path(flake_file)223pytest-impure> 224pytest-impure> flake_dir = absolute_flake_path.parent or Path()225pytest-impure> absolute_flake_dir = flake_dir.resolve()226pytest-impure> 227pytest-impure> # Use a shallow URL because worktrees may not have the full history.228pytest-impure> # For subflakes, nix needs the URL to point to the git root229pytest-impure> # with a dir= parameter rather than the subdirectory directly.230pytest-impure> if work_dir:231pytest-impure> git_root = Path(work_dir).resolve()232pytest-impure> relative_dir = absolute_flake_dir.relative_to(git_root)233pytest-impure> flake_url = f"git+file://{git_root}?shallow=1"234pytest-impure> if str(relative_dir) != ".":235pytest-impure> flake_url += f"&dir={relative_dir}"236pytest-impure> else:237pytest-impure> flake_url = f"git+file://{absolute_flake_dir}?shallow=1"238pytest-impure> 239pytest-impure> result = subprocess.run(240pytest-impure> [241pytest-impure> "nix",242pytest-impure> "flake",243pytest-impure> "update",244pytest-impure> "--flake",245pytest-impure> flake_url,246pytest-impure> input_name,247pytest-impure> ],248pytest-impure> cwd=str(flake_dir),249pytest-impure> capture_output=True,250pytest-impure> text=True,251pytest-impure> check=True,252pytest-impure> )253pytest-impure> 254pytest-impure> # Check if there was a warning about non-existent input255pytest-impure> if result.stderr and "does not match any input" in result.stderr:256pytest-impure> logger.warning(257pytest-impure> "Failed to update input %s in %s: %s",258pytest-impure> input_name,259pytest-impure> flake_file,260pytest-impure> result.stderr.strip(),261pytest-impure> )262pytest-impure> 263pytest-impure> logger.info(264pytest-impure> "Successfully updated flake input: %s in %s",265pytest-impure> input_name,266pytest-impure> flake_file,267pytest-impure> )268pytest-impure> except subprocess.CalledProcessError as e:269pytest-impure> stderr_output = e.stderr.strip() if e.stderr else "No stderr output"270pytest-impure> stdout_output = e.stdout.strip() if e.stdout else "No stdout output"271pytest-impure> logger.exception(272pytest-impure> "Failed to update flake input %s in %s. Exit code: %d\nStdout: %s\nStderr: %s",273pytest-impure> input_name,274pytest-impure> flake_file,275pytest-impure> e.returncode,276pytest-impure> stdout_output,277pytest-impure> stderr_output,278pytest-impure> )279pytest-impure> msg = (280pytest-impure> f"Failed to update flake input {input_name} in {flake_file}: {e}\n"281pytest-impure> f"Stderr: {stderr_output}"282pytest-impure> )283pytest-impure> > raise FlakeServiceError(msg) from e284pytest-impure> E update_flake_inputs.exceptions.FlakeServiceError: Failed to update flake input flake-utils in flake.nix: Command '['nix', 'flake', 'update', '--flake', 'git+file:///build/tmpie236ebw?shallow=1', 'flake-utils']' returned non-zero exit status 1.285pytest-impure> E Stderr: warning: you don't have Internet access; disabling some network-dependent features286pytest-impure> E error:287pytest-impure> E … while updating the lock file of flake 'git+file:///build/tmpie236ebw?ref=refs/heads/master&rev=c612154fdd8ea6da984559356ee0f13da2faa699&shallow=1'288pytest-impure> E 289pytest-impure> E … while updating the flake input 'flake-utils'290pytest-impure> E 291pytest-impure> E … while fetching the input 'github:numtide/flake-utils'292pytest-impure> E 293pytest-impure> E error: unable to download 'https://api.github.com/repos/numtide/flake-utils/commits/HEAD': Could not resolve hostname (6) Could not resolve host: api.github.com294pytest-impure> 295pytest-impure> src/update_flake_inputs/flake_service.py:235: FlakeServiceError296pytest-impure> ----------------------------- Captured stdout call -----------------------------297pytest-impure> Initialized empty Git repository in /build/tmpie236ebw/.git/298pytest-impure> [master (root-commit) c612154] Initial commit299pytest-impure> 2 files changed, 55 insertions(+)300pytest-impure> create mode 100644 flake.lock301pytest-impure> create mode 100644 flake.nix302pytest-impure> ----------------------------- Captured stderr call -----------------------------303pytest-impure> hint: Using 'master' as the name for the initial branch. This default branch name304pytest-impure> hint: will change to "main" in Git 3.0. To configure the initial branch name305pytest-impure> hint: to use in all of your new repositories, which will suppress this warning,306pytest-impure> hint: call:307pytest-impure> hint:308pytest-impure> hint: git config --global init.defaultBranch <name>309pytest-impure> hint:310pytest-impure> hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and311pytest-impure> hint: 'development'. The just-created branch can be renamed via this command:312pytest-impure> hint:313pytest-impure> hint: git branch -m <name>314pytest-impure> hint:315pytest-impure> hint: Disable this message with "git config set advice.defaultBranchName false"316pytest-impure> ------------------------------ Captured log call -------------------------------317pytest-impure> ERROR update_flake_inputs.flake_service:flake_service.py:223 Failed to update flake input flake-utils in flake.nix. Exit code: 1318pytest-impure> Stdout: No stdout output319pytest-impure> Stderr: warning: you don't have Internet access; disabling some network-dependent features320pytest-impure> error:321pytest-impure> … while updating the lock file of flake 'git+file:///build/tmpie236ebw?ref=refs/heads/master&rev=c612154fdd8ea6da984559356ee0f13da2faa699&shallow=1'322pytest-impure> 323pytest-impure> … while updating the flake input 'flake-utils'324pytest-impure> 325pytest-impure> … while fetching the input 'github:numtide/flake-utils'326pytest-impure> 327pytest-impure> error: unable to download 'https://api.github.com/repos/numtide/flake-utils/commits/HEAD': Could not resolve hostname (6) Could not resolve host: api.github.com328pytest-impure> Traceback (most recent call last):329pytest-impure> File "/build/src/src/update_flake_inputs/flake_service.py", line 191, in update_flake_input330pytest-impure> result = subprocess.run(331pytest-impure> [332pytest-impure> ...<10 lines>...333pytest-impure> check=True,334pytest-impure> )335pytest-impure> File "/nix/store/6xbk6d4rk2dc9c3kbdx0rkvn2knfqcmp-python3-3.13.13-env/lib/python3.13/subprocess.py", line 577, in run336pytest-impure> raise CalledProcessError(retcode, process.args,337pytest-impure> output=stdout, stderr=stderr)338pytest-impure> subprocess.CalledProcessError: Command '['nix', 'flake', 'update', '--flake', 'git+file:///build/tmpie236ebw?shallow=1', 'flake-utils']' returned non-zero exit status 1.339pytest-impure> _________________ TestFlakeService.test_update_subflake_input __________________340pytest-impure> 341pytest-impure> self = <update_flake_inputs.flake_service.FlakeService object at 0x7ffff59a7bf0>342pytest-impure> input_name = 'flake-utils', flake_file = 'flake.nix'343pytest-impure> work_dir = '/build/tmp3cuqdbqt'344pytest-impure> 345pytest-impure> def update_flake_input(346pytest-impure> self,347pytest-impure> input_name: str,348pytest-impure> flake_file: str,349pytest-impure> work_dir: str | None = None,350pytest-impure> ) -> None:351pytest-impure> """Update a specific flake input.352pytest-impure> 353pytest-impure> Args:354pytest-impure> input_name: Name of the input to update355pytest-impure> flake_file: Path to the flake file356pytest-impure> work_dir: Optional working directory to resolve flake file path from357pytest-impure> 358pytest-impure> """359pytest-impure> try:360pytest-impure> logger.info("Updating flake input: %s in %s", input_name, flake_file)361pytest-impure> 362pytest-impure> # If work_dir is provided, resolve the flake file relative to it363pytest-impure> absolute_flake_path = Path(work_dir) / flake_file if work_dir else Path(flake_file)364pytest-impure> 365pytest-impure> flake_dir = absolute_flake_path.parent or Path()366pytest-impure> absolute_flake_dir = flake_dir.resolve()367pytest-impure> 368pytest-impure> # Use a shallow URL because worktrees may not have the full history.369pytest-impure> # For subflakes, nix needs the URL to point to the git root370pytest-impure> # with a dir= parameter rather than the subdirectory directly.371pytest-impure> if work_dir:372pytest-impure> git_root = Path(work_dir).resolve()373pytest-impure> relative_dir = absolute_flake_dir.relative_to(git_root)374pytest-impure> flake_url = f"git+file://{git_root}?shallow=1"375pytest-impure> if str(relative_dir) != ".":376pytest-impure> flake_url += f"&dir={relative_dir}"377pytest-impure> else:378pytest-impure> flake_url = f"git+file://{absolute_flake_dir}?shallow=1"379pytest-impure> 380pytest-impure> > result = subprocess.run(381pytest-impure> [382pytest-impure> "nix",383pytest-impure> "flake",384pytest-impure> "update",385pytest-impure> "--flake",386pytest-impure> flake_url,387pytest-impure> input_name,388pytest-impure> ],389pytest-impure> cwd=str(flake_dir),390pytest-impure> capture_output=True,391pytest-impure> text=True,392pytest-impure> check=True,393pytest-impure> )394pytest-impure> 395pytest-impure> src/update_flake_inputs/flake_service.py:191: 396pytest-impure> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 397pytest-impure> 398pytest-impure> input = None, capture_output = True, timeout = None, check = True399pytest-impure> popenargs = (['nix', 'flake', 'update', '--flake', 'git+file:///build/tmp3cuqdbqt?shallow=1', 'flake-utils'],)400pytest-impure> kwargs = {'cwd': '/build/tmp3cuqdbqt', 'stderr': -1, 'stdout': -1, 'text': True}401pytest-impure> process = <Popen: returncode: 1 args: ['nix', 'flake', 'update', '--flake', 'git+file:...>402pytest-impure> stdout = ''403pytest-impure> stderr = "warning: you don't have Internet access; disabling some network-dependent features\nerror:\n … while updating t...b.com/repos/numtide/flake-utils/commits/HEAD': Could not resolve hostname (6) Could not resolve host: api.github.com\n"404pytest-impure> retcode = 1405pytest-impure> 406pytest-impure> def run(*popenargs,407pytest-impure> input=None, capture_output=False, timeout=None, check=False, **kwargs):408pytest-impure> """Run command with arguments and return a CompletedProcess instance.409pytest-impure> 410pytest-impure> The returned instance will have attributes args, returncode, stdout and411pytest-impure> stderr. By default, stdout and stderr are not captured, and those attributes412pytest-impure> will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them,413pytest-impure> or pass capture_output=True to capture both.414pytest-impure> 415pytest-impure> If check is True and the exit code was non-zero, it raises a416pytest-impure> CalledProcessError. The CalledProcessError object will have the return code417pytest-impure> in the returncode attribute, and output & stderr attributes if those streams418pytest-impure> were captured.419pytest-impure> 420pytest-impure> If timeout (seconds) is given and the process takes too long,421pytest-impure> a TimeoutExpired exception will be raised.422pytest-impure> 423pytest-impure> There is an optional argument "input", allowing you to424pytest-impure> pass bytes or a string to the subprocess's stdin. If you use this argument425pytest-impure> you may not also use the Popen constructor's "stdin" argument, as426pytest-impure> it will be used internally.427pytest-impure> 428pytest-impure> By default, all communication is in bytes, and therefore any "input" should429pytest-impure> be bytes, and the stdout and stderr will be bytes. If in text mode, any430pytest-impure> "input" should be a string, and stdout and stderr will be strings decoded431pytest-impure> according to locale encoding, or by "encoding" if set. Text mode is432pytest-impure> triggered by setting any of text, encoding, errors or universal_newlines.433pytest-impure> 434pytest-impure> The other arguments are the same as for the Popen constructor.435pytest-impure> """436pytest-impure> if input is not None:437pytest-impure> if kwargs.get('stdin') is not None:438pytest-impure> raise ValueError('stdin and input arguments may not both be used.')439pytest-impure> kwargs['stdin'] = PIPE440pytest-impure> 441pytest-impure> if capture_output:442pytest-impure> if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None:443pytest-impure> raise ValueError('stdout and stderr arguments may not be used '444pytest-impure> 'with capture_output.')445pytest-impure> kwargs['stdout'] = PIPE446pytest-impure> kwargs['stderr'] = PIPE447pytest-impure> 448pytest-impure> with Popen(*popenargs, **kwargs) as process:449pytest-impure> try:450pytest-impure> stdout, stderr = process.communicate(input, timeout=timeout)451pytest-impure> except TimeoutExpired as exc:452pytest-impure> process.kill()453pytest-impure> if _mswindows:454pytest-impure> # Windows accumulates the output in a single blocking455pytest-impure> # read() call run on child threads, with the timeout456pytest-impure> # being done in a join() on those threads. communicate()457pytest-impure> # _after_ kill() is required to collect that and add it458pytest-impure> # to the exception.459pytest-impure> exc.stdout, exc.stderr = process.communicate()460pytest-impure> else:461pytest-impure> # POSIX _communicate already populated the output so462pytest-impure> # far into the TimeoutExpired exception.463pytest-impure> process.wait()464pytest-impure> raise465pytest-impure> except: # Including KeyboardInterrupt, communicate handled that.466pytest-impure> process.kill()467pytest-impure> # We don't call process.wait() as .__exit__ does that for us.468pytest-impure> raise469pytest-impure> retcode = process.poll()470pytest-impure> if check and retcode:471pytest-impure> > raise CalledProcessError(retcode, process.args,472pytest-impure> output=stdout, stderr=stderr)473pytest-impure> E subprocess.CalledProcessError: Command '['nix', 'flake', 'update', '--flake', 'git+file:///build/tmp3cuqdbqt?shallow=1', 'flake-utils']' returned non-zero exit status 1.474pytest-impure> 475pytest-impure> /nix/store/6xbk6d4rk2dc9c3kbdx0rkvn2knfqcmp-python3-3.13.13-env/lib/python3.13/subprocess.py:577: CalledProcessError476pytest-impure> 477pytest-impure> The above exception was the direct cause of the following exception:478pytest-impure> 479pytest-impure> self = <tests.test_flake_service.TestFlakeService object at 0x7ffff667d8c0>480pytest-impure> flake_service = <update_flake_inputs.flake_service.FlakeService object at 0x7ffff59a7bf0>481pytest-impure> fixtures_path = PosixPath('/build/src/tests/fixtures')482pytest-impure> 483pytest-impure> @pytest.mark.impure484pytest-impure> def test_update_subflake_input(485pytest-impure> self,486pytest-impure> flake_service: FlakeService,487pytest-impure> fixtures_path: Path,488pytest-impure> ) -> None:489pytest-impure> """Test updating a flake input in a subdirectory (subflake)."""490pytest-impure> with tempfile.TemporaryDirectory() as temp_dir:491pytest-impure> temp_path = Path(temp_dir)492pytest-impure> 493pytest-impure> # Copy minimal flake to a subdirectory494pytest-impure> sub_dir = temp_path / "sub"495pytest-impure> sub_dir.mkdir()496pytest-impure> shutil.copy(497pytest-impure> fixtures_path / "minimal" / "flake.nix",498pytest-impure> sub_dir / "flake.nix",499pytest-impure> )500pytest-impure> shutil.copy(501pytest-impure> fixtures_path / "minimal" / "flake.lock",502pytest-impure> sub_dir / "flake.lock",503pytest-impure> )504pytest-impure> 505pytest-impure> # Copy minimal flake to root506pytest-impure> shutil.copy(507pytest-impure> fixtures_path / "minimal" / "flake.nix",508pytest-impure> temp_path / "flake.nix",509pytest-impure> )510pytest-impure> shutil.copy(511pytest-impure> fixtures_path / "minimal" / "flake.lock",512pytest-impure> temp_path / "flake.lock",513pytest-impure> )514pytest-impure> 515pytest-impure> # Initialize git repo in temp directory516pytest-impure> subprocess.run(["git", "init"], cwd=temp_path, check=True)517pytest-impure> subprocess.run(["git", "add", "."], cwd=temp_path, check=True)518pytest-impure> subprocess.run(519pytest-impure> ["git", "commit", "-m", "Initial commit"],520pytest-impure> cwd=temp_path,521pytest-impure> check=True,522pytest-impure> env={523pytest-impure> **os.environ,524pytest-impure> "GIT_AUTHOR_NAME": "Test User",525pytest-impure> "GIT_AUTHOR_EMAIL": "test@example.com",526pytest-impure> "GIT_COMMITTER_NAME": "Test User",527pytest-impure> "GIT_COMMITTER_EMAIL": "test@example.com",528pytest-impure> },529pytest-impure> )530pytest-impure> 531pytest-impure> original_root_lock = json.loads((temp_path / "flake.lock").read_text())532pytest-impure> original_root_rev = original_root_lock["nodes"]["flake-utils"]["locked"]["rev"]533pytest-impure> 534pytest-impure> original_sub_lock = json.loads((sub_dir / "flake.lock").read_text())535pytest-impure> original_sub_rev = original_sub_lock["nodes"]["flake-utils"]["locked"]["rev"]536pytest-impure> 537pytest-impure> # Update flake-utils in the root flake538pytest-impure> > flake_service.update_flake_input("flake-utils", "flake.nix", str(temp_path))539pytest-impure> 540pytest-impure> tests/test_flake_service.py:272: 541pytest-impure> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 542pytest-impure> 543pytest-impure> self = <update_flake_inputs.flake_service.FlakeService object at 0x7ffff59a7bf0>544pytest-impure> input_name = 'flake-utils', flake_file = 'flake.nix'545pytest-impure> work_dir = '/build/tmp3cuqdbqt'546pytest-impure> 547pytest-impure> def update_flake_input(548pytest-impure> self,549pytest-impure> input_name: str,550pytest-impure> flake_file: str,551pytest-impure> work_dir: str | None = None,552pytest-impure> ) -> None:553pytest-impure> """Update a specific flake input.554pytest-impure> 555pytest-impure> Args:556pytest-impure> input_name: Name of the input to update557pytest-impure> flake_file: Path to the flake file558pytest-impure> work_dir: Optional working directory to resolve flake file path from559pytest-impure> 560pytest-impure> """561pytest-impure> try:562pytest-impure> logger.info("Updating flake input: %s in %s", input_name, flake_file)563pytest-impure> 564pytest-impure> # If work_dir is provided, resolve the flake file relative to it565pytest-impure> absolute_flake_path = Path(work_dir) / flake_file if work_dir else Path(flake_file)566pytest-impure> 567pytest-impure> flake_dir = absolute_flake_path.parent or Path()568pytest-impure> absolute_flake_dir = flake_dir.resolve()569pytest-impure> 570pytest-impure> # Use a shallow URL because worktrees may not have the full history.571pytest-impure> # For subflakes, nix needs the URL to point to the git root572pytest-impure> # with a dir= parameter rather than the subdirectory directly.573pytest-impure> if work_dir:574pytest-impure> git_root = Path(work_dir).resolve()575pytest-impure> relative_dir = absolute_flake_dir.relative_to(git_root)576pytest-impure> flake_url = f"git+file://{git_root}?shallow=1"577pytest-impure> if str(relative_dir) != ".":578pytest-impure> flake_url += f"&dir={relative_dir}"579pytest-impure> else:580pytest-impure> flake_url = f"git+file://{absolute_flake_dir}?shallow=1"581pytest-impure> 582pytest-impure> result = subprocess.run(583pytest-impure> [584pytest-impure> "nix",585pytest-impure> "flake",586pytest-impure> "update",587pytest-impure> "--flake",588pytest-impure> flake_url,589pytest-impure> input_name,590pytest-impure> ],591pytest-impure> cwd=str(flake_dir),592pytest-impure> capture_output=True,593pytest-impure> text=True,594pytest-impure> check=True,595pytest-impure> )596pytest-impure> 597pytest-impure> # Check if there was a warning about non-existent input598pytest-impure> if result.stderr and "does not match any input" in result.stderr:599pytest-impure> logger.warning(600pytest-impure> "Failed to update input %s in %s: %s",601pytest-impure> input_name,602pytest-impure> flake_file,603pytest-impure> result.stderr.strip(),604pytest-impure> )605pytest-impure> 606pytest-impure> logger.info(607pytest-impure> "Successfully updated flake input: %s in %s",608pytest-impure> input_name,609pytest-impure> flake_file,610pytest-impure> )611pytest-impure> except subprocess.CalledProcessError as e:612pytest-impure> stderr_output = e.stderr.strip() if e.stderr else "No stderr output"613pytest-impure> stdout_output = e.stdout.strip() if e.stdout else "No stdout output"614pytest-impure> logger.exception(615pytest-impure> "Failed to update flake input %s in %s. Exit code: %d\nStdout: %s\nStderr: %s",616pytest-impure> input_name,617pytest-impure> flake_file,618pytest-impure> e.returncode,619pytest-impure> stdout_output,620pytest-impure> stderr_output,621pytest-impure> )622pytest-impure> msg = (623pytest-impure> f"Failed to update flake input {input_name} in {flake_file}: {e}\n"624pytest-impure> f"Stderr: {stderr_output}"625pytest-impure> )626pytest-impure> > raise FlakeServiceError(msg) from e627pytest-impure> E update_flake_inputs.exceptions.FlakeServiceError: Failed to update flake input flake-utils in flake.nix: Command '['nix', 'flake', 'update', '--flake', 'git+file:///build/tmp3cuqdbqt?shallow=1', 'flake-utils']' returned non-zero exit status 1.628pytest-impure> E Stderr: warning: you don't have Internet access; disabling some network-dependent features629pytest-impure> E error:630pytest-impure> E … while updating the lock file of flake 'git+file:///build/tmp3cuqdbqt?ref=refs/heads/master&rev=d2cdb1d9198fb7a86ced6dfb30bc1fa04fce58a8&shallow=1'631pytest-impure> E 632pytest-impure> E … while updating the flake input 'flake-utils'633pytest-impure> E 634pytest-impure> E … while fetching the input 'github:numtide/flake-utils'635pytest-impure> E 636pytest-impure> E error: unable to download 'https://api.github.com/repos/numtide/flake-utils/commits/HEAD': Could not resolve hostname (6) Could not resolve host: api.github.com637pytest-impure> 638pytest-impure> src/update_flake_inputs/flake_service.py:235: FlakeServiceError639pytest-impure> ----------------------------- Captured stdout call -----------------------------640pytest-impure> Initialized empty Git repository in /build/tmp3cuqdbqt/.git/641pytest-impure> [master (root-commit) d2cdb1d] Initial commit642pytest-impure> 4 files changed, 110 insertions(+)643pytest-impure> create mode 100644 flake.lock644pytest-impure> create mode 100644 flake.nix645pytest-impure> create mode 100644 sub/flake.lock646pytest-impure> create mode 100644 sub/flake.nix647pytest-impure> ----------------------------- Captured stderr call -----------------------------648pytest-impure> hint: Using 'master' as the name for the initial branch. This default branch name649pytest-impure> hint: will change to "main" in Git 3.0. To configure the initial branch name650pytest-impure> hint: to use in all of your new repositories, which will suppress this warning,651pytest-impure> hint: call:652pytest-impure> hint:653pytest-impure> hint: git config --global init.defaultBranch <name>654pytest-impure> hint:655pytest-impure> hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and656pytest-impure> hint: 'development'. The just-created branch can be renamed via this command:657pytest-impure> hint:658pytest-impure> hint: git branch -m <name>659pytest-impure> hint:660pytest-impure> hint: Disable this message with "git config set advice.defaultBranchName false"661pytest-impure> ------------------------------ Captured log call -------------------------------662pytest-impure> ERROR update_flake_inputs.flake_service:flake_service.py:223 Failed to update flake input flake-utils in flake.nix. Exit code: 1663pytest-impure> Stdout: No stdout output664pytest-impure> Stderr: warning: you don't have Internet access; disabling some network-dependent features665pytest-impure> error:666pytest-impure> … while updating the lock file of flake 'git+file:///build/tmp3cuqdbqt?ref=refs/heads/master&rev=d2cdb1d9198fb7a86ced6dfb30bc1fa04fce58a8&shallow=1'667pytest-impure> 668pytest-impure> … while updating the flake input 'flake-utils'669pytest-impure> 670pytest-impure> … while fetching the input 'github:numtide/flake-utils'671pytest-impure> 672pytest-impure> error: unable to download 'https://api.github.com/repos/numtide/flake-utils/commits/HEAD': Could not resolve hostname (6) Could not resolve host: api.github.com673pytest-impure> Traceback (most recent call last):674pytest-impure> File "/build/src/src/update_flake_inputs/flake_service.py", line 191, in update_flake_input675pytest-impure> result = subprocess.run(676pytest-impure> [677pytest-impure> ...<10 lines>...678pytest-impure> check=True,679pytest-impure> )680pytest-impure> File "/nix/store/6xbk6d4rk2dc9c3kbdx0rkvn2knfqcmp-python3-3.13.13-env/lib/python3.13/subprocess.py", line 577, in run681pytest-impure> raise CalledProcessError(retcode, process.args,682pytest-impure> output=stdout, stderr=stderr)683pytest-impure> subprocess.CalledProcessError: Command '['nix', 'flake', 'update', '--flake', 'git+file:///build/tmp3cuqdbqt?shallow=1', 'flake-utils']' returned non-zero exit status 1.684pytest-impure> ___________ TestProcessFlakeUpdates.test_with_updatable_flake_input ____________685pytest-impure> 686pytest-impure> self = <tests.test_process_flake_updates.TestProcessFlakeUpdates object at 0x7ffff63a11d0>687pytest-impure> tmp_path = PosixPath('/build/pytest-of-nixbld/pytest-0/test_with_updatable_flake_inpu0')688pytest-impure> fixtures_path = PosixPath('/build/src/tests/fixtures')689pytest-impure> 690pytest-impure> @pytest.mark.impure691pytest-impure> def test_with_updatable_flake_input(692pytest-impure> self,693pytest-impure> tmp_path: Path,694pytest-impure> fixtures_path: Path,695pytest-impure> ) -> None:696pytest-impure> """Test PR creation when flake input has available updates."""697pytest-impure> # Create a flake with flake-utils that can be updated698pytest-impure> flake_content = """{699pytest-impure> inputs = {700pytest-impure> flake-utils.url = "github:numtide/flake-utils";701pytest-impure> };702pytest-impure> 703pytest-impure> outputs = { self, flake-utils }: {704pytest-impure> # Test flake with updatable input705pytest-impure> };706pytest-impure> }"""707pytest-impure> 708pytest-impure> (tmp_path / "flake.nix").write_text(flake_content)709pytest-impure> 710pytest-impure> # Copy old lock file from minimal fixture711pytest-impure> shutil.copy(712pytest-impure> fixtures_path / "minimal" / "flake.lock",713pytest-impure> tmp_path / "flake.lock",714pytest-impure> )715pytest-impure> 716pytest-impure> _setup_git_repo(tmp_path)717pytest-impure> 718pytest-impure> # Change to test directory719pytest-impure> original_cwd = Path.cwd()720pytest-impure> os.chdir(tmp_path)721pytest-impure> 722pytest-impure> try:723pytest-impure> # Create test services724pytest-impure> flake_service = FlakeService()725pytest-impure> test_gitea_service = MockGiteaService()726pytest-impure> 727pytest-impure> # Process updates728pytest-impure> > process_flake_updates(729pytest-impure> flake_service,730pytest-impure> test_gitea_service,731pytest-impure> "",732pytest-impure> "main",733pytest-impure> "",734pytest-impure> auto_merge=False,735pytest-impure> )736pytest-impure> 737pytest-impure> tests/test_process_flake_updates.py:222: 738pytest-impure> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 739pytest-impure> 740pytest-impure> flake_service = <update_flake_inputs.flake_service.FlakeService object at 0x7ffff631a850>741pytest-impure> gitea_service = MockGiteaService(api_url='https://gitea.example.com', token='test-token', owner='test-owner', repo='test-repo', git_au...tions[bot]', git_committer_email='gitea-actions[bot]@noreply.gitea.io', merge_style='default', pr_creation_attempts=[])742pytest-impure> exclude_patterns = '', base_branch = 'main', branch_suffix = ''743pytest-impure> 744pytest-impure> def process_flake_updates( # noqa: PLR0913745pytest-impure> flake_service: FlakeService,746pytest-impure> gitea_service: GiteaService,747pytest-impure> exclude_patterns: str,748pytest-impure> base_branch: str,749pytest-impure> branch_suffix: str,750pytest-impure> *,751pytest-impure> auto_merge: bool,752pytest-impure> ) -> None:753pytest-impure> """Process all flake updates.754pytest-impure> 755pytest-impure> Args:756pytest-impure> flake_service: Flake service instance757pytest-impure> gitea_service: Gitea service instance758pytest-impure> exclude_patterns: Patterns to exclude759pytest-impure> base_branch: Base branch for PRs760pytest-impure> branch_suffix: Optional suffix to append to branch names761pytest-impure> auto_merge: Whether to automatically merge PRs762pytest-impure> 763pytest-impure> """764pytest-impure> # Discover flake files765pytest-impure> flakes = flake_service.discover_flake_files(exclude_patterns)766pytest-impure> if not flakes:767pytest-impure> logger.info("No flake files found")768pytest-impure> return769pytest-impure> 770pytest-impure> logger.info("Found %d flake files to process", len(flakes))771pytest-impure> 772pytest-impure> failed_inputs: list[str] = []773pytest-impure> 774pytest-impure> # Process each flake775pytest-impure> for flake in flakes:776pytest-impure> logger.info("Processing flake: %s", flake.file_path)777pytest-impure> logger.info("Inputs to update: %s", ", ".join(flake.inputs))778pytest-impure> 779pytest-impure> # Don't include '.' for root directory780pytest-impure> parent_path = Path(flake.file_path).parent781pytest-impure> parent_suffix = "" if parent_path == Path() else f" in {parent_path}"782pytest-impure> parent_branch = "" if parent_path == Path() else f"-{parent_path}"783pytest-impure> suffix = branch_suffix.strip().replace("/", "-").strip("-")784pytest-impure> 785pytest-impure> # Update each input786pytest-impure> for input_name in flake.inputs:787pytest-impure> try:788pytest-impure> branch_name = f"update{parent_branch}-{input_name}"789pytest-impure> branch_name = branch_name.replace("/", "-").strip("-")790pytest-impure> if suffix:791pytest-impure> branch_name = f"{branch_name}-{suffix}"792pytest-impure> 793pytest-impure> logger.info(794pytest-impure> "Updating input %s in %s (branch: %s)",795pytest-impure> input_name,796pytest-impure> flake.file_path,797pytest-impure> branch_name,798pytest-impure> )799pytest-impure> 800pytest-impure> # Create worktree and update input801pytest-impure> with gitea_service.worktree(branch_name, base_branch) as worktree_path:802pytest-impure> # Update the input803pytest-impure> flake_service.update_flake_input(804pytest-impure> input_name,805pytest-impure> flake.file_path,806pytest-impure> str(worktree_path),807pytest-impure> )808pytest-impure> 809pytest-impure> # Commit changes810pytest-impure> commit_message = f"Update {input_name}{parent_suffix}"811pytest-impure> if gitea_service.commit_changes(812pytest-impure> branch_name,813pytest-impure> commit_message,814pytest-impure> worktree_path,815pytest-impure> ):816pytest-impure> # Create pull request817pytest-impure> pr_title = commit_message818pytest-impure> pr_body = (819pytest-impure> f"This PR updates the `{input_name}` input "820pytest-impure> f"in `{flake.file_path}`.\n\n"821pytest-impure> "Generated by update-flake-inputs action."822pytest-impure> )823pytest-impure> gitea_service.create_pull_request(824pytest-impure> branch_name,825pytest-impure> base_branch,826pytest-impure> pr_title,827pytest-impure> pr_body,828pytest-impure> auto_merge=auto_merge,829pytest-impure> )830pytest-impure> else:831pytest-impure> logger.info(832pytest-impure> "No changes for input %s in %s",833pytest-impure> input_name,834pytest-impure> flake.file_path,835pytest-impure> )836pytest-impure> gitea_service.delete_branch(branch_name)837pytest-impure> 838pytest-impure> except Exception:839pytest-impure> logger.exception(840pytest-impure> "Failed to update input %s in %s",841pytest-impure> input_name,842pytest-impure> flake.file_path,843pytest-impure> )844pytest-impure> failed_inputs.append(f"{input_name} in {flake.file_path}")845pytest-impure> 846pytest-impure> if failed_inputs:847pytest-impure> msg = f"Failed to process {len(failed_inputs)} input(s): {', '.join(failed_inputs)}"848pytest-impure> > raise UpdateFlakeInputsError(msg)849pytest-impure> E update_flake_inputs.exceptions.UpdateFlakeInputsError: Failed to process 1 input(s): flake-utils in flake.nix850pytest-impure> 851pytest-impure> src/update_flake_inputs/cli.py:268: UpdateFlakeInputsError852pytest-impure> ----------------------------- Captured stdout call -----------------------------853pytest-impure> Initialized empty Git repository in /build/pytest-of-nixbld/pytest-0/test_with_updatable_flake_inpu0/.git/854pytest-impure> [main (root-commit) bbff15b] Initial commit855pytest-impure> 2 files changed, 53 insertions(+)856pytest-impure> create mode 100644 flake.lock857pytest-impure> create mode 100644 flake.nix858pytest-impure> Initialized empty Git repository in /build/pytest-of-nixbld/pytest-0/remote-test_with_updatable_flake_inpu0.git/859pytest-impure> branch 'main' set up to track 'origin/main'.860pytest-impure> branch 'update-flake-utils' set up to track 'origin/main'.861pytest-impure> HEAD is now at bbff15b Initial commit862pytest-impure> ----------------------------- Captured stderr call -----------------------------863pytest-impure> hint: Using 'master' as the name for the initial branch. This default branch name864pytest-impure> hint: will change to "main" in Git 3.0. To configure the initial branch name865pytest-impure> hint: to use in all of your new repositories, which will suppress this warning,866pytest-impure> hint: call:867pytest-impure> hint:868pytest-impure> hint: git config --global init.defaultBranch <name>869pytest-impure> hint:870pytest-impure> hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and871pytest-impure> hint: 'development'. The just-created branch can be renamed via this command:872pytest-impure> hint:873pytest-impure> hint: git branch -m <name>874pytest-impure> hint:875pytest-impure> hint: Disable this message with "git config set advice.defaultBranchName false"876pytest-impure> To /build/pytest-of-nixbld/pytest-0/remote-test_with_updatable_flake_inpu0.git877pytest-impure> * [new branch] main -> main878pytest-impure> From /build/pytest-of-nixbld/pytest-0/remote-test_with_updatable_flake_inpu0879pytest-impure> * branch main -> FETCH_HEAD880pytest-impure> Preparing worktree (new branch 'update-flake-utils')881pytest-impure> ------------------------------ Captured log call -------------------------------882pytest-impure> ERROR update_flake_inputs.flake_service:flake_service.py:223 Failed to update flake input flake-utils in flake.nix. Exit code: 1883pytest-impure> Stdout: No stdout output884pytest-impure> Stderr: warning: you don't have Internet access; disabling some network-dependent features885pytest-impure> error:886pytest-impure> … while updating the lock file of flake 'git+file:///build/flake-update-1d5jjx7m/update-flake-utils?ref=refs/heads/update-flake-utils&rev=bbff15b6f162877e44145838d3ba224dc1faac8b&shallow=1'887pytest-impure> 888pytest-impure> … while updating the flake input 'flake-utils'889pytest-impure> 890pytest-impure> … while fetching the input 'github:numtide/flake-utils'891pytest-impure> 892pytest-impure> error: unable to download 'https://api.github.com/repos/numtide/flake-utils/commits/HEAD': Could not resolve hostname (6) Could not resolve host: api.github.com893pytest-impure> Traceback (most recent call last):894pytest-impure> File "/build/src/src/update_flake_inputs/flake_service.py", line 191, in update_flake_input895pytest-impure> result = subprocess.run(896pytest-impure> [897pytest-impure> ...<10 lines>...898pytest-impure> check=True,899pytest-impure> )900pytest-impure> File "/nix/store/6xbk6d4rk2dc9c3kbdx0rkvn2knfqcmp-python3-3.13.13-env/lib/python3.13/subprocess.py", line 577, in run901pytest-impure> raise CalledProcessError(retcode, process.args,902pytest-impure> output=stdout, stderr=stderr)903pytest-impure> subprocess.CalledProcessError: Command '['nix', 'flake', 'update', '--flake', 'git+file:///build/flake-update-1d5jjx7m/update-flake-utils?shallow=1', 'flake-utils']' returned non-zero exit status 1.904pytest-impure> ERROR update_flake_inputs.cli:cli.py:259 Failed to update input flake-utils in flake.nix905pytest-impure> Traceback (most recent call last):906pytest-impure> File "/build/src/src/update_flake_inputs/flake_service.py", line 191, in update_flake_input907pytest-impure> result = subprocess.run(908pytest-impure> [909pytest-impure> ...<10 lines>...910pytest-impure> check=True,911pytest-impure> )912pytest-impure> File "/nix/store/6xbk6d4rk2dc9c3kbdx0rkvn2knfqcmp-python3-3.13.13-env/lib/python3.13/subprocess.py", line 577, in run913pytest-impure> raise CalledProcessError(retcode, process.args,914pytest-impure> output=stdout, stderr=stderr)915pytest-impure> subprocess.CalledProcessError: Command '['nix', 'flake', 'update', '--flake', 'git+file:///build/flake-update-1d5jjx7m/update-flake-utils?shallow=1', 'flake-utils']' returned non-zero exit status 1.916pytest-impure> 917pytest-impure> The above exception was the direct cause of the following exception:918pytest-impure> 919pytest-impure> Traceback (most recent call last):920pytest-impure> File "/build/src/src/update_flake_inputs/cli.py", line 223, in process_flake_updates921pytest-impure> flake_service.update_flake_input(922pytest-impure> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^923pytest-impure> input_name,924pytest-impure> ^^^^^^^^^^^925pytest-impure> flake.file_path,926pytest-impure> ^^^^^^^^^^^^^^^^927pytest-impure> str(worktree_path),928pytest-impure> ^^^^^^^^^^^^^^^^^^^929pytest-impure> )930pytest-impure> ^931pytest-impure> File "/build/src/src/update_flake_inputs/flake_service.py", line 235, in update_flake_input932pytest-impure> raise FlakeServiceError(msg) from e933pytest-impure> update_flake_inputs.exceptions.FlakeServiceError: Failed to update flake input flake-utils in flake.nix: Command '['nix', 'flake', 'update', '--flake', 'git+file:///build/flake-update-1d5jjx7m/update-flake-utils?shallow=1', 'flake-utils']' returned non-zero exit status 1.934pytest-impure> Stderr: warning: you don't have Internet access; disabling some network-dependent features935pytest-impure> error:936pytest-impure> … while updating the lock file of flake 'git+file:///build/flake-update-1d5jjx7m/update-flake-utils?ref=refs/heads/update-flake-utils&rev=bbff15b6f162877e44145838d3ba224dc1faac8b&shallow=1'937pytest-impure> 938pytest-impure> … while updating the flake input 'flake-utils'939pytest-impure> 940pytest-impure> … while fetching the input 'github:numtide/flake-utils'941pytest-impure> 942pytest-impure> error: unable to download 'https://api.github.com/repos/numtide/flake-utils/commits/HEAD': Could not resolve hostname (6) Could not resolve host: api.github.com943pytest-impure> _____ TestProcessFlakeUpdates.test_worktree_based_on_base_branch_not_head ______944pytest-impure> 945pytest-impure> self = <tests.test_process_flake_updates.TestProcessFlakeUpdates object at 0x7ffff631dba0>946pytest-impure> tmp_path = PosixPath('/build/pytest-of-nixbld/pytest-0/test_worktree_based_on_base_br0')947pytest-impure> fixtures_path = PosixPath('/build/src/tests/fixtures')948pytest-impure> 949pytest-impure> @pytest.mark.impure950pytest-impure> def test_worktree_based_on_base_branch_not_head(951pytest-impure> self,952pytest-impure> tmp_path: Path,953pytest-impure> fixtures_path: Path,954pytest-impure> ) -> None:955pytest-impure> """Test that update branches are based on base_branch, not current HEAD.956pytest-impure> 957pytest-impure> When the action is triggered from a non-main branch, the worktree958pytest-impure> should still be based on origin/<base_branch> so that commits from959pytest-impure> the triggering branch don't leak into the update branch.960pytest-impure> """961pytest-impure> flake_content = """{962pytest-impure> inputs = {963pytest-impure> flake-utils.url = "github:numtide/flake-utils";964pytest-impure> };965pytest-impure> 966pytest-impure> outputs = { self, flake-utils }: {967pytest-impure> # Test flake with updatable input968pytest-impure> };969pytest-impure> }"""970pytest-impure> 971pytest-impure> (tmp_path / "flake.nix").write_text(flake_content)972pytest-impure> 973pytest-impure> shutil.copy(974pytest-impure> fixtures_path / "minimal" / "flake.lock",975pytest-impure> tmp_path / "flake.lock",976pytest-impure> )977pytest-impure> 978pytest-impure> _setup_git_repo(tmp_path)979pytest-impure> 980pytest-impure> # Create a feature branch with an extra commit981pytest-impure> git_env = {982pytest-impure> **os.environ,983pytest-impure> "GIT_AUTHOR_NAME": "Test User",984pytest-impure> "GIT_AUTHOR_EMAIL": "test@example.com",985pytest-impure> "GIT_COMMITTER_NAME": "Test User",986pytest-impure> "GIT_COMMITTER_EMAIL": "test@example.com",987pytest-impure> }988pytest-impure> subprocess.run(989pytest-impure> ["git", "checkout", "-b", "feature-branch"],990pytest-impure> cwd=tmp_path,991pytest-impure> check=True,992pytest-impure> )993pytest-impure> (tmp_path / "extra-file.txt").write_text("feature branch content")994pytest-impure> subprocess.run(["git", "add", "."], cwd=tmp_path, check=True)995pytest-impure> subprocess.run(996pytest-impure> ["git", "commit", "-m", "Feature branch commit"],997pytest-impure> cwd=tmp_path,998pytest-impure> check=True,999pytest-impure> env=git_env,1000pytest-impure> )1001pytest-impure> 1002pytest-impure> # Stay on feature-branch (simulating action triggered from non-main branch)1003pytest-impure> original_cwd = Path.cwd()1004pytest-impure> os.chdir(tmp_path)1005pytest-impure> 1006pytest-impure> try:1007pytest-impure> flake_service = FlakeService()1008pytest-impure> test_gitea_service = MockGiteaService()1009pytest-impure> 1010pytest-impure> > process_flake_updates(1011pytest-impure> flake_service,1012pytest-impure> test_gitea_service,1013pytest-impure> "",1014pytest-impure> "main",1015pytest-impure> "",1016pytest-impure> auto_merge=False,1017pytest-impure> )1018pytest-impure> 1019pytest-impure> tests/test_process_flake_updates.py:328: 1020pytest-impure> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 1021pytest-impure> 1022pytest-impure> flake_service = <update_flake_inputs.flake_service.FlakeService object at 0x7ffff6399450>1023pytest-impure> gitea_service = MockGiteaService(api_url='https://gitea.example.com', token='test-token', owner='test-owner', repo='test-repo', git_au...tions[bot]', git_committer_email='gitea-actions[bot]@noreply.gitea.io', merge_style='default', pr_creation_attempts=[])1024pytest-impure> exclude_patterns = '', base_branch = 'main', branch_suffix = ''1025pytest-impure> 1026pytest-impure> def process_flake_updates( # noqa: PLR09131027pytest-impure> flake_service: FlakeService,1028pytest-impure> gitea_service: GiteaService,1029pytest-impure> exclude_patterns: str,1030pytest-impure> base_branch: str,1031pytest-impure> branch_suffix: str,1032pytest-impure> *,1033pytest-impure> auto_merge: bool,1034pytest-impure> ) -> None:1035pytest-impure> """Process all flake updates.1036pytest-impure> 1037pytest-impure> Args:1038pytest-impure> flake_service: Flake service instance1039pytest-impure> gitea_service: Gitea service instance1040pytest-impure> exclude_patterns: Patterns to exclude1041pytest-impure> base_branch: Base branch for PRs1042pytest-impure> branch_suffix: Optional suffix to append to branch names1043pytest-impure> auto_merge: Whether to automatically merge PRs1044pytest-impure> 1045pytest-impure> """1046pytest-impure> # Discover flake files1047pytest-impure> flakes = flake_service.discover_flake_files(exclude_patterns)1048pytest-impure> if not flakes:1049pytest-impure> logger.info("No flake files found")1050pytest-impure> return1051pytest-impure> 1052pytest-impure> logger.info("Found %d flake files to process", len(flakes))1053pytest-impure> 1054pytest-impure> failed_inputs: list[str] = []1055pytest-impure> 1056pytest-impure> # Process each flake1057pytest-impure> for flake in flakes:1058pytest-impure> logger.info("Processing flake: %s", flake.file_path)1059pytest-impure> logger.info("Inputs to update: %s", ", ".join(flake.inputs))1060pytest-impure> 1061pytest-impure> # Don't include '.' for root directory1062pytest-impure> parent_path = Path(flake.file_path).parent1063pytest-impure> parent_suffix = "" if parent_path == Path() else f" in {parent_path}"1064pytest-impure> parent_branch = "" if parent_path == Path() else f"-{parent_path}"1065pytest-impure> suffix = branch_suffix.strip().replace("/", "-").strip("-")1066pytest-impure> 1067pytest-impure> # Update each input1068pytest-impure> for input_name in flake.inputs:1069pytest-impure> try:1070pytest-impure> branch_name = f"update{parent_branch}-{input_name}"1071pytest-impure> branch_name = branch_name.replace("/", "-").strip("-")1072pytest-impure> if suffix:1073pytest-impure> branch_name = f"{branch_name}-{suffix}"1074pytest-impure> 1075pytest-impure> logger.info(1076pytest-impure> "Updating input %s in %s (branch: %s)",1077pytest-impure> input_name,1078pytest-impure> flake.file_path,1079pytest-impure> branch_name,1080pytest-impure> )1081pytest-impure> 1082pytest-impure> # Create worktree and update input1083pytest-impure> with gitea_service.worktree(branch_name, base_branch) as worktree_path:1084pytest-impure> # Update the input1085pytest-impure> flake_service.update_flake_input(1086pytest-impure> input_name,1087pytest-impure> flake.file_path,1088pytest-impure> str(worktree_path),1089pytest-impure> )1090pytest-impure> 1091pytest-impure> # Commit changes1092pytest-impure> commit_message = f"Update {input_name}{parent_suffix}"1093pytest-impure> if gitea_service.commit_changes(1094pytest-impure> branch_name,1095pytest-impure> commit_message,1096pytest-impure> worktree_path,1097pytest-impure> ):1098pytest-impure> # Create pull request1099pytest-impure> pr_title = commit_message1100pytest-impure> pr_body = (1101pytest-impure> f"This PR updates the `{input_name}` input "1102pytest-impure> f"in `{flake.file_path}`.\n\n"1103pytest-impure> "Generated by update-flake-inputs action."1104pytest-impure> )1105pytest-impure> gitea_service.create_pull_request(1106pytest-impure> branch_name,1107pytest-impure> base_branch,1108pytest-impure> pr_title,1109pytest-impure> pr_body,1110pytest-impure> auto_merge=auto_merge,1111pytest-impure> )1112pytest-impure> else:1113pytest-impure> logger.info(1114pytest-impure> "No changes for input %s in %s",1115pytest-impure> input_name,1116pytest-impure> flake.file_path,1117pytest-impure> )1118pytest-impure> gitea_service.delete_branch(branch_name)1119pytest-impure> 1120pytest-impure> except Exception:1121pytest-impure> logger.exception(1122pytest-impure> "Failed to update input %s in %s",1123pytest-impure> input_name,1124pytest-impure> flake.file_path,1125pytest-impure> )1126pytest-impure> failed_inputs.append(f"{input_name} in {flake.file_path}")1127pytest-impure> 1128pytest-impure> if failed_inputs:1129pytest-impure> msg = f"Failed to process {len(failed_inputs)} input(s): {', '.join(failed_inputs)}"1130pytest-impure> > raise UpdateFlakeInputsError(msg)1131pytest-impure> E update_flake_inputs.exceptions.UpdateFlakeInputsError: Failed to process 1 input(s): flake-utils in flake.nix1132pytest-impure> 1133pytest-impure> src/update_flake_inputs/cli.py:268: UpdateFlakeInputsError1134pytest-impure> ----------------------------- Captured stdout call -----------------------------1135pytest-impure> Initialized empty Git repository in /build/pytest-of-nixbld/pytest-0/test_worktree_based_on_base_br0/.git/1136pytest-impure> [main (root-commit) a50a376] Initial commit1137pytest-impure> 2 files changed, 53 insertions(+)1138pytest-impure> create mode 100644 flake.lock1139pytest-impure> create mode 100644 flake.nix1140pytest-impure> Initialized empty Git repository in /build/pytest-of-nixbld/pytest-0/remote-test_worktree_based_on_base_br0.git/1141pytest-impure> branch 'main' set up to track 'origin/main'.1142pytest-impure> [feature-branch 663ddb2] Feature branch commit1143pytest-impure> 1 file changed, 1 insertion(+)1144pytest-impure> create mode 100644 extra-file.txt1145pytest-impure> branch 'update-flake-utils' set up to track 'origin/main'.1146pytest-impure> HEAD is now at a50a376 Initial commit1147pytest-impure> ----------------------------- Captured stderr call -----------------------------1148pytest-impure> hint: Using 'master' as the name for the initial branch. This default branch name1149pytest-impure> hint: will change to "main" in Git 3.0. To configure the initial branch name1150pytest-impure> hint: to use in all of your new repositories, which will suppress this warning,1151pytest-impure> hint: call:1152pytest-impure> hint:1153pytest-impure> hint: git config --global init.defaultBranch <name>1154pytest-impure> hint:1155pytest-impure> hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and1156pytest-impure> hint: 'development'. The just-created branch can be renamed via this command:1157pytest-impure> hint:1158pytest-impure> hint: git branch -m <name>1159pytest-impure> hint:1160pytest-impure> hint: Disable this message with "git config set advice.defaultBranchName false"1161pytest-impure> To /build/pytest-of-nixbld/pytest-0/remote-test_worktree_based_on_base_br0.git1162pytest-impure> * [new branch] main -> main1163pytest-impure> Switched to a new branch 'feature-branch'1164pytest-impure> From /build/pytest-of-nixbld/pytest-0/remote-test_worktree_based_on_base_br01165pytest-impure> * branch main -> FETCH_HEAD1166pytest-impure> Preparing worktree (new branch 'update-flake-utils')1167pytest-impure> ------------------------------ Captured log call -------------------------------1168pytest-impure> ERROR update_flake_inputs.flake_service:flake_service.py:223 Failed to update flake input flake-utils in flake.nix. Exit code: 11169pytest-impure> Stdout: No stdout output1170pytest-impure> Stderr: warning: you don't have Internet access; disabling some network-dependent features1171pytest-impure> error:1172pytest-impure> … while updating the lock file of flake 'git+file:///build/flake-update-lci346_l/update-flake-utils?ref=refs/heads/update-flake-utils&rev=a50a376960fc04a96fb222bb60ae835f6229096c&shallow=1'1173pytest-impure> 1174pytest-impure> … while updating the flake input 'flake-utils'1175pytest-impure> 1176pytest-impure> … while fetching the input 'github:numtide/flake-utils'1177pytest-impure> 1178pytest-impure> error: unable to download 'https://api.github.com/repos/numtide/flake-utils/commits/HEAD': Could not resolve hostname (6) Could not resolve host: api.github.com1179pytest-impure> Traceback (most recent call last):1180pytest-impure> File "/build/src/src/update_flake_inputs/flake_service.py", line 191, in update_flake_input1181pytest-impure> result = subprocess.run(1182pytest-impure> [1183pytest-impure> ...<10 lines>...1184pytest-impure> check=True,1185pytest-impure> )1186pytest-impure> File "/nix/store/6xbk6d4rk2dc9c3kbdx0rkvn2knfqcmp-python3-3.13.13-env/lib/python3.13/subprocess.py", line 577, in run1187pytest-impure> raise CalledProcessError(retcode, process.args,1188pytest-impure> output=stdout, stderr=stderr)1189pytest-impure> subprocess.CalledProcessError: Command '['nix', 'flake', 'update', '--flake', 'git+file:///build/flake-update-lci346_l/update-flake-utils?shallow=1', 'flake-utils']' returned non-zero exit status 1.1190pytest-impure> ERROR update_flake_inputs.cli:cli.py:259 Failed to update input flake-utils in flake.nix1191pytest-impure> Traceback (most recent call last):1192pytest-impure> File "/build/src/src/update_flake_inputs/flake_service.py", line 191, in update_flake_input1193pytest-impure> result = subprocess.run(1194pytest-impure> [1195pytest-impure> ...<10 lines>...1196pytest-impure> check=True,1197pytest-impure> )1198pytest-impure> File "/nix/store/6xbk6d4rk2dc9c3kbdx0rkvn2knfqcmp-python3-3.13.13-env/lib/python3.13/subprocess.py", line 577, in run1199pytest-impure> raise CalledProcessError(retcode, process.args,1200pytest-impure> output=stdout, stderr=stderr)1201pytest-impure> subprocess.CalledProcessError: Command '['nix', 'flake', 'update', '--flake', 'git+file:///build/flake-update-lci346_l/update-flake-utils?shallow=1', 'flake-utils']' returned non-zero exit status 1.1202pytest-impure> 1203pytest-impure> The above exception was the direct cause of the following exception:1204pytest-impure> 1205pytest-impure> Traceback (most recent call last):1206pytest-impure> File "/build/src/src/update_flake_inputs/cli.py", line 223, in process_flake_updates1207pytest-impure> flake_service.update_flake_input(1208pytest-impure> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^1209pytest-impure> input_name,1210pytest-impure> ^^^^^^^^^^^1211pytest-impure> flake.file_path,1212pytest-impure> ^^^^^^^^^^^^^^^^1213pytest-impure> str(worktree_path),1214pytest-impure> ^^^^^^^^^^^^^^^^^^^1215pytest-impure> )1216pytest-impure> ^1217pytest-impure> File "/build/src/src/update_flake_inputs/flake_service.py", line 235, in update_flake_input1218pytest-impure> raise FlakeServiceError(msg) from e1219pytest-impure> update_flake_inputs.exceptions.FlakeServiceError: Failed to update flake input flake-utils in flake.nix: Command '['nix', 'flake', 'update', '--flake', 'git+file:///build/flake-update-lci346_l/update-flake-utils?shallow=1', 'flake-utils']' returned non-zero exit status 1.1220pytest-impure> Stderr: warning: you don't have Internet access; disabling some network-dependent features1221pytest-impure> error:1222pytest-impure> … while updating the lock file of flake 'git+file:///build/flake-update-lci346_l/update-flake-utils?ref=refs/heads/update-flake-utils&rev=a50a376960fc04a96fb222bb60ae835f6229096c&shallow=1'1223pytest-impure> 1224pytest-impure> … while updating the flake input 'flake-utils'1225pytest-impure> 1226pytest-impure> … while fetching the input 'github:numtide/flake-utils'1227pytest-impure> 1228pytest-impure> error: unable to download 'https://api.github.com/repos/numtide/flake-utils/commits/HEAD': Could not resolve hostname (6) Could not resolve host: api.github.com1229pytest-impure> ___________ TestProcessFlakeUpdates.test_custom_git_author_committer ___________1230pytest-impure> 1231pytest-impure> self = <tests.test_process_flake_updates.TestProcessFlakeUpdates object at 0x7ffff631df30>1232pytest-impure> tmp_path = PosixPath('/build/pytest-of-nixbld/pytest-0/test_custom_git_author_committ0')1233pytest-impure> fixtures_path = PosixPath('/build/src/tests/fixtures')1234pytest-impure> 1235pytest-impure> @pytest.mark.impure1236pytest-impure> def test_custom_git_author_committer(1237pytest-impure> self,1238pytest-impure> tmp_path: Path,1239pytest-impure> fixtures_path: Path,1240pytest-impure> ) -> None:1241pytest-impure> """Test that custom git author/committer configuration is used."""1242pytest-impure> # Create a flake with flake-utils1243pytest-impure> flake_content = """{1244pytest-impure> inputs = {1245pytest-impure> flake-utils.url = "github:numtide/flake-utils";1246pytest-impure> };1247pytest-impure> 1248pytest-impure> outputs = { self, flake-utils }: {1249pytest-impure> # Test flake1250pytest-impure> };1251pytest-impure> }"""1252pytest-impure> 1253pytest-impure> (tmp_path / "flake.nix").write_text(flake_content)1254pytest-impure> 1255pytest-impure> # Copy old lock file from minimal fixture1256pytest-impure> shutil.copy(1257pytest-impure> fixtures_path / "minimal" / "flake.lock",1258pytest-impure> tmp_path / "flake.lock",1259pytest-impure> )1260pytest-impure> 1261pytest-impure> _setup_git_repo(tmp_path)1262pytest-impure> 1263pytest-impure> # Change to test directory1264pytest-impure> original_cwd = Path.cwd()1265pytest-impure> os.chdir(tmp_path)1266pytest-impure> 1267pytest-impure> try:1268pytest-impure> # Create test services with custom git author/committer1269pytest-impure> flake_service = FlakeService()1270pytest-impure> test_gitea_service = MockGiteaService()1271pytest-impure> test_gitea_service.git_author_name = "Custom Bot"1272pytest-impure> test_gitea_service.git_author_email = "custom@bot.com"1273pytest-impure> test_gitea_service.git_committer_name = "Custom Committer"1274pytest-impure> test_gitea_service.git_committer_email = "committer@bot.com"1275pytest-impure> 1276pytest-impure> # Process updates1277pytest-impure> > process_flake_updates(1278pytest-impure> flake_service,1279pytest-impure> test_gitea_service,1280pytest-impure> "",1281pytest-impure> "main",1282pytest-impure> "",1283pytest-impure> auto_merge=False,1284pytest-impure> )1285pytest-impure> 1286pytest-impure> tests/test_process_flake_updates.py:398: 1287pytest-impure> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 1288pytest-impure> 1289pytest-impure> flake_service = <update_flake_inputs.flake_service.FlakeService object at 0x7ffff65c3e30>1290pytest-impure> gitea_service = MockGiteaService(api_url='https://gitea.example.com', token='test-token', owner='test-owner', repo='test-repo', git_au...itter_name='Custom Committer', git_committer_email='committer@bot.com', merge_style='default', pr_creation_attempts=[])1291pytest-impure> exclude_patterns = '', base_branch = 'main', branch_suffix = ''1292pytest-impure> 1293pytest-impure> def process_flake_updates( # noqa: PLR09131294pytest-impure> flake_service: FlakeService,1295pytest-impure> gitea_service: GiteaService,1296pytest-impure> exclude_patterns: str,1297pytest-impure> base_branch: str,1298pytest-impure> branch_suffix: str,1299pytest-impure> *,1300pytest-impure> auto_merge: bool,1301pytest-impure> ) -> None:1302pytest-impure> """Process all flake updates.1303pytest-impure> 1304pytest-impure> Args:1305pytest-impure> flake_service: Flake service instance1306pytest-impure> gitea_service: Gitea service instance1307pytest-impure> exclude_patterns: Patterns to exclude1308pytest-impure> base_branch: Base branch for PRs1309pytest-impure> branch_suffix: Optional suffix to append to branch names1310pytest-impure> auto_merge: Whether to automatically merge PRs1311pytest-impure> 1312pytest-impure> """1313pytest-impure> # Discover flake files1314pytest-impure> flakes = flake_service.discover_flake_files(exclude_patterns)1315pytest-impure> if not flakes:1316pytest-impure> logger.info("No flake files found")1317pytest-impure> return1318pytest-impure> 1319pytest-impure> logger.info("Found %d flake files to process", len(flakes))1320pytest-impure> 1321pytest-impure> failed_inputs: list[str] = []1322pytest-impure> 1323pytest-impure> # Process each flake1324pytest-impure> for flake in flakes:1325pytest-impure> logger.info("Processing flake: %s", flake.file_path)1326pytest-impure> logger.info("Inputs to update: %s", ", ".join(flake.inputs))1327pytest-impure> 1328pytest-impure> # Don't include '.' for root directory1329pytest-impure> parent_path = Path(flake.file_path).parent1330pytest-impure> parent_suffix = "" if parent_path == Path() else f" in {parent_path}"1331pytest-impure> parent_branch = "" if parent_path == Path() else f"-{parent_path}"1332pytest-impure> suffix = branch_suffix.strip().replace("/", "-").strip("-")1333pytest-impure> 1334pytest-impure> # Update each input1335pytest-impure> for input_name in flake.inputs:1336pytest-impure> try:1337pytest-impure> branch_name = f"update{parent_branch}-{input_name}"1338pytest-impure> branch_name = branch_name.replace("/", "-").strip("-")1339pytest-impure> if suffix:1340pytest-impure> branch_name = f"{branch_name}-{suffix}"1341pytest-impure> 1342pytest-impure> logger.info(1343pytest-impure> "Updating input %s in %s (branch: %s)",1344pytest-impure> input_name,1345pytest-impure> flake.file_path,1346pytest-impure> branch_name,1347pytest-impure> )1348pytest-impure> 1349pytest-impure> # Create worktree and update input1350pytest-impure> with gitea_service.worktree(branch_name, base_branch) as worktree_path:1351pytest-impure> # Update the input1352pytest-impure> flake_service.update_flake_input(1353pytest-impure> input_name,1354pytest-impure> flake.file_path,1355pytest-impure> str(worktree_path),1356pytest-impure> )1357pytest-impure> 1358pytest-impure> # Commit changes1359pytest-impure> commit_message = f"Update {input_name}{parent_suffix}"1360pytest-impure> if gitea_service.commit_changes(1361pytest-impure> branch_name,1362pytest-impure> commit_message,1363pytest-impure> worktree_path,1364pytest-impure> ):1365pytest-impure> # Create pull request1366pytest-impure> pr_title = commit_message1367pytest-impure> pr_body = (1368pytest-impure> f"This PR updates the `{input_name}` input "1369pytest-impure> f"in `{flake.file_path}`.\n\n"1370pytest-impure> "Generated by update-flake-inputs action."1371pytest-impure> )1372pytest-impure> gitea_service.create_pull_request(1373pytest-impure> branch_name,1374pytest-impure> base_branch,1375pytest-impure> pr_title,1376pytest-impure> pr_body,1377pytest-impure> auto_merge=auto_merge,1378pytest-impure> )1379pytest-impure> else:1380pytest-impure> logger.info(1381pytest-impure> "No changes for input %s in %s",1382pytest-impure> input_name,1383pytest-impure> flake.file_path,1384pytest-impure> )1385pytest-impure> gitea_service.delete_branch(branch_name)1386pytest-impure> 1387pytest-impure> except Exception:1388pytest-impure> logger.exception(1389pytest-impure> "Failed to update input %s in %s",1390pytest-impure> input_name,1391pytest-impure> flake.file_path,1392pytest-impure> )1393pytest-impure> failed_inputs.append(f"{input_name} in {flake.file_path}")1394pytest-impure> 1395pytest-impure> if failed_inputs:1396pytest-impure> msg = f"Failed to process {len(failed_inputs)} input(s): {', '.join(failed_inputs)}"1397pytest-impure> > raise UpdateFlakeInputsError(msg)1398pytest-impure> E update_flake_inputs.exceptions.UpdateFlakeInputsError: Failed to process 1 input(s): flake-utils in flake.nix1399pytest-impure> 1400pytest-impure> src/update_flake_inputs/cli.py:268: UpdateFlakeInputsError1401pytest-impure> ----------------------------- Captured stdout call -----------------------------1402pytest-impure> Initialized empty Git repository in /build/pytest-of-nixbld/pytest-0/test_custom_git_author_committ0/.git/1403pytest-impure> [main (root-commit) e76969a] Initial commit1404pytest-impure> 2 files changed, 53 insertions(+)1405pytest-impure> create mode 100644 flake.lock1406pytest-impure> create mode 100644 flake.nix1407pytest-impure> Initialized empty Git repository in /build/pytest-of-nixbld/pytest-0/remote-test_custom_git_author_committ0.git/1408pytest-impure> branch 'main' set up to track 'origin/main'.1409pytest-impure> branch 'update-flake-utils' set up to track 'origin/main'.1410pytest-impure> HEAD is now at e76969a Initial commit1411pytest-impure> ----------------------------- Captured stderr call -----------------------------1412pytest-impure> hint: Using 'master' as the name for the initial branch. This default branch name1413pytest-impure> hint: will change to "main" in Git 3.0. To configure the initial branch name1414pytest-impure> hint: to use in all of your new repositories, which will suppress this warning,1415pytest-impure> hint: call:1416pytest-impure> hint:1417pytest-impure> hint: git config --global init.defaultBranch <name>1418pytest-impure> hint:1419pytest-impure> hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and1420pytest-impure> hint: 'development'. The just-created branch can be renamed via this command:1421pytest-impure> hint:1422pytest-impure> hint: git branch -m <name>1423pytest-impure> hint:1424pytest-impure> hint: Disable this message with "git config set advice.defaultBranchName false"1425pytest-impure> To /build/pytest-of-nixbld/pytest-0/remote-test_custom_git_author_committ0.git1426pytest-impure> * [new branch] main -> main1427pytest-impure> From /build/pytest-of-nixbld/pytest-0/remote-test_custom_git_author_committ01428pytest-impure> * branch main -> FETCH_HEAD1429pytest-impure> Preparing worktree (new branch 'update-flake-utils')1430pytest-impure> ------------------------------ Captured log call -------------------------------1431pytest-impure> ERROR update_flake_inputs.flake_service:flake_service.py:223 Failed to update flake input flake-utils in flake.nix. Exit code: 11432pytest-impure> Stdout: No stdout output1433pytest-impure> Stderr: warning: you don't have Internet access; disabling some network-dependent features1434pytest-impure> error:1435pytest-impure> … while updating the lock file of flake 'git+file:///build/flake-update-1mxkk0bl/update-flake-utils?ref=refs/heads/update-flake-utils&rev=e76969a56e490f9164deef4862231976d2b6a18c&shallow=1'1436pytest-impure> 1437pytest-impure> … while updating the flake input 'flake-utils'1438pytest-impure> 1439pytest-impure> … while fetching the input 'github:numtide/flake-utils'1440pytest-impure> 1441pytest-impure> error: unable to download 'https://api.github.com/repos/numtide/flake-utils/commits/HEAD': Could not resolve hostname (6) Could not resolve host: api.github.com1442pytest-impure> Traceback (most recent call last):1443pytest-impure> File "/build/src/src/update_flake_inputs/flake_service.py", line 191, in update_flake_input1444pytest-impure> result = subprocess.run(1445pytest-impure> [1446pytest-impure> ...<10 lines>...1447pytest-impure> check=True,1448pytest-impure> )1449pytest-impure> File "/nix/store/6xbk6d4rk2dc9c3kbdx0rkvn2knfqcmp-python3-3.13.13-env/lib/python3.13/subprocess.py", line 577, in run1450pytest-impure> raise CalledProcessError(retcode, process.args,1451pytest-impure> output=stdout, stderr=stderr)1452pytest-impure> subprocess.CalledProcessError: Command '['nix', 'flake', 'update', '--flake', 'git+file:///build/flake-update-1mxkk0bl/update-flake-utils?shallow=1', 'flake-utils']' returned non-zero exit status 1.1453pytest-impure> ERROR update_flake_inputs.cli:cli.py:259 Failed to update input flake-utils in flake.nix1454pytest-impure> Traceback (most recent call last):1455pytest-impure> File "/build/src/src/update_flake_inputs/flake_service.py", line 191, in update_flake_input1456pytest-impure> result = subprocess.run(1457pytest-impure> [1458pytest-impure> ...<10 lines>...1459pytest-impure> check=True,1460pytest-impure> )1461pytest-impure> File "/nix/store/6xbk6d4rk2dc9c3kbdx0rkvn2knfqcmp-python3-3.13.13-env/lib/python3.13/subprocess.py", line 577, in run1462pytest-impure> raise CalledProcessError(retcode, process.args,1463pytest-impure> output=stdout, stderr=stderr)1464pytest-impure> subprocess.CalledProcessError: Command '['nix', 'flake', 'update', '--flake', 'git+file:///build/flake-update-1mxkk0bl/update-flake-utils?shallow=1', 'flake-utils']' returned non-zero exit status 1.1465pytest-impure> 1466pytest-impure> The above exception was the direct cause of the following exception:1467pytest-impure> 1468pytest-impure> Traceback (most recent call last):1469pytest-impure> File "/build/src/src/update_flake_inputs/cli.py", line 223, in process_flake_updates1470pytest-impure> flake_service.update_flake_input(1471pytest-impure> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^1472pytest-impure> input_name,1473pytest-impure> ^^^^^^^^^^^1474pytest-impure> flake.file_path,1475pytest-impure> ^^^^^^^^^^^^^^^^1476pytest-impure> str(worktree_path),1477pytest-impure> ^^^^^^^^^^^^^^^^^^^1478pytest-impure> )1479pytest-impure> ^1480pytest-impure> File "/build/src/src/update_flake_inputs/flake_service.py", line 235, in update_flake_input1481pytest-impure> raise FlakeServiceError(msg) from e1482pytest-impure> update_flake_inputs.exceptions.FlakeServiceError: Failed to update flake input flake-utils in flake.nix: Command '['nix', 'flake', 'update', '--flake', 'git+file:///build/flake-update-1mxkk0bl/update-flake-utils?shallow=1', 'flake-utils']' returned non-zero exit status 1.1483pytest-impure> Stderr: warning: you don't have Internet access; disabling some network-dependent features1484pytest-impure> error:1485pytest-impure> … while updating the lock file of flake 'git+file:///build/flake-update-1mxkk0bl/update-flake-utils?ref=refs/heads/update-flake-utils&rev=e76969a56e490f9164deef4862231976d2b6a18c&shallow=1'1486pytest-impure> 1487pytest-impure> … while updating the flake input 'flake-utils'1488pytest-impure> 1489pytest-impure> … while fetching the input 'github:numtide/flake-utils'1490pytest-impure> 1491pytest-impure> error: unable to download 'https://api.github.com/repos/numtide/flake-utils/commits/HEAD': Could not resolve hostname (6) Could not resolve host: api.github.com1492pytest-impure> __________________ TestProcessFlakeUpdates.test_branch_suffix __________________1493pytest-impure> 1494pytest-impure> self = <tests.test_process_flake_updates.TestProcessFlakeUpdates object at 0x7ffff5a6c170>1495pytest-impure> tmp_path = PosixPath('/build/pytest-of-nixbld/pytest-0/test_branch_suffix0')1496pytest-impure> fixtures_path = PosixPath('/build/src/tests/fixtures')1497pytest-impure> 1498pytest-impure> @pytest.mark.impure1499pytest-impure> def test_branch_suffix(1500pytest-impure> self,1501pytest-impure> tmp_path: Path,1502pytest-impure> fixtures_path: Path,1503pytest-impure> ) -> None:1504pytest-impure> """Test that branch suffix is properly appended to branch names."""1505pytest-impure> # Create a flake with flake-utils1506pytest-impure> flake_content = """{1507pytest-impure> inputs = {1508pytest-impure> flake-utils.url = "github:numtide/flake-utils";1509pytest-impure> };1510pytest-impure> 1511pytest-impure> outputs = { self, flake-utils }: {1512pytest-impure> # Test flake1513pytest-impure> };1514pytest-impure> }"""1515pytest-impure> 1516pytest-impure> (tmp_path / "flake.nix").write_text(flake_content)1517pytest-impure> 1518pytest-impure> # Copy old lock file from minimal fixture1519pytest-impure> shutil.copy(1520pytest-impure> fixtures_path / "minimal" / "flake.lock",1521pytest-impure> tmp_path / "flake.lock",1522pytest-impure> )1523pytest-impure> 1524pytest-impure> _setup_git_repo(tmp_path)1525pytest-impure> 1526pytest-impure> # Change to test directory1527pytest-impure> original_cwd = Path.cwd()1528pytest-impure> os.chdir(tmp_path)1529pytest-impure> 1530pytest-impure> try:1531pytest-impure> # Create test services1532pytest-impure> flake_service = FlakeService()1533pytest-impure> test_gitea_service = MockGiteaService()1534pytest-impure> 1535pytest-impure> # Process updates with branch suffix1536pytest-impure> > process_flake_updates(1537pytest-impure> flake_service,1538pytest-impure> test_gitea_service,1539pytest-impure> "",1540pytest-impure> "main",1541pytest-impure> "my-suffix",1542pytest-impure> auto_merge=False,1543pytest-impure> )1544pytest-impure> 1545pytest-impure> tests/test_process_flake_updates.py:465: 1546pytest-impure> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 1547pytest-impure> 1548pytest-impure> flake_service = <update_flake_inputs.flake_service.FlakeService object at 0x7ffff63949b0>1549pytest-impure> gitea_service = MockGiteaService(api_url='https://gitea.example.com', token='test-token', owner='test-owner', repo='test-repo', git_au...tions[bot]', git_committer_email='gitea-actions[bot]@noreply.gitea.io', merge_style='default', pr_creation_attempts=[])1550pytest-impure> exclude_patterns = '', base_branch = 'main', branch_suffix = 'my-suffix'1551pytest-impure> 1552pytest-impure> def process_flake_updates( # noqa: PLR09131553pytest-impure> flake_service: FlakeService,1554pytest-impure> gitea_service: GiteaService,1555pytest-impure> exclude_patterns: str,1556pytest-impure> base_branch: str,1557pytest-impure> branch_suffix: str,1558pytest-impure> *,1559pytest-impure> auto_merge: bool,1560pytest-impure> ) -> None:1561pytest-impure> """Process all flake updates.1562pytest-impure> 1563pytest-impure> Args:1564pytest-impure> flake_service: Flake service instance1565pytest-impure> gitea_service: Gitea service instance1566pytest-impure> exclude_patterns: Patterns to exclude1567pytest-impure> base_branch: Base branch for PRs1568pytest-impure> branch_suffix: Optional suffix to append to branch names1569pytest-impure> auto_merge: Whether to automatically merge PRs1570pytest-impure> 1571pytest-impure> """1572pytest-impure> # Discover flake files1573pytest-impure> flakes = flake_service.discover_flake_files(exclude_patterns)1574pytest-impure> if not flakes:1575pytest-impure> logger.info("No flake files found")1576pytest-impure> return1577pytest-impure> 1578pytest-impure> logger.info("Found %d flake files to process", len(flakes))1579pytest-impure> 1580pytest-impure> failed_inputs: list[str] = []1581pytest-impure> 1582pytest-impure> # Process each flake1583pytest-impure> for flake in flakes:1584pytest-impure> logger.info("Processing flake: %s", flake.file_path)1585pytest-impure> logger.info("Inputs to update: %s", ", ".join(flake.inputs))1586pytest-impure> 1587pytest-impure> # Don't include '.' for root directory1588pytest-impure> parent_path = Path(flake.file_path).parent1589pytest-impure> parent_suffix = "" if parent_path == Path() else f" in {parent_path}"1590pytest-impure> parent_branch = "" if parent_path == Path() else f"-{parent_path}"1591pytest-impure> suffix = branch_suffix.strip().replace("/", "-").strip("-")1592pytest-impure> 1593pytest-impure> # Update each input1594pytest-impure> for input_name in flake.inputs:1595pytest-impure> try:1596pytest-impure> branch_name = f"update{parent_branch}-{input_name}"1597pytest-impure> branch_name = branch_name.replace("/", "-").strip("-")1598pytest-impure> if suffix:1599pytest-impure> branch_name = f"{branch_name}-{suffix}"1600pytest-impure> 1601pytest-impure> logger.info(1602pytest-impure> "Updating input %s in %s (branch: %s)",1603pytest-impure> input_name,1604pytest-impure> flake.file_path,1605pytest-impure> branch_name,1606pytest-impure> )1607pytest-impure> 1608pytest-impure> # Create worktree and update input1609pytest-impure> with gitea_service.worktree(branch_name, base_branch) as worktree_path:1610pytest-impure> # Update the input1611pytest-impure> flake_service.update_flake_input(1612pytest-impure> input_name,1613pytest-impure> flake.file_path,1614pytest-impure> str(worktree_path),1615pytest-impure> )1616pytest-impure> 1617pytest-impure> # Commit changes1618pytest-impure> commit_message = f"Update {input_name}{parent_suffix}"1619pytest-impure> if gitea_service.commit_changes(1620pytest-impure> branch_name,1621pytest-impure> commit_message,1622pytest-impure> worktree_path,1623pytest-impure> ):1624pytest-impure> # Create pull request1625pytest-impure> pr_title = commit_message1626pytest-impure> pr_body = (1627pytest-impure> f"This PR updates the `{input_name}` input "1628pytest-impure> f"in `{flake.file_path}`.\n\n"1629pytest-impure> "Generated by update-flake-inputs action."1630pytest-impure> )1631pytest-impure> gitea_service.create_pull_request(1632pytest-impure> branch_name,1633pytest-impure> base_branch,1634pytest-impure> pr_title,1635pytest-impure> pr_body,1636pytest-impure> auto_merge=auto_merge,1637pytest-impure> )1638pytest-impure> else:1639pytest-impure> logger.info(1640pytest-impure> "No changes for input %s in %s",1641pytest-impure> input_name,1642pytest-impure> flake.file_path,1643pytest-impure> )1644pytest-impure> gitea_service.delete_branch(branch_name)1645pytest-impure> 1646pytest-impure> except Exception:1647pytest-impure> logger.exception(1648pytest-impure> "Failed to update input %s in %s",1649pytest-impure> input_name,1650pytest-impure> flake.file_path,1651pytest-impure> )1652pytest-impure> failed_inputs.append(f"{input_name} in {flake.file_path}")1653pytest-impure> 1654pytest-impure> if failed_inputs:1655pytest-impure> msg = f"Failed to process {len(failed_inputs)} input(s): {', '.join(failed_inputs)}"1656pytest-impure> > raise UpdateFlakeInputsError(msg)1657pytest-impure> E update_flake_inputs.exceptions.UpdateFlakeInputsError: Failed to process 1 input(s): flake-utils in flake.nix1658pytest-impure> 1659pytest-impure> src/update_flake_inputs/cli.py:268: UpdateFlakeInputsError1660pytest-impure> ----------------------------- Captured stdout call -----------------------------1661pytest-impure> Initialized empty Git repository in /build/pytest-of-nixbld/pytest-0/test_branch_suffix0/.git/1662pytest-impure> [main (root-commit) 9bb82d8] Initial commit1663pytest-impure> 2 files changed, 53 insertions(+)1664pytest-impure> create mode 100644 flake.lock1665pytest-impure> create mode 100644 flake.nix1666pytest-impure> Initialized empty Git repository in /build/pytest-of-nixbld/pytest-0/remote-test_branch_suffix0.git/1667pytest-impure> branch 'main' set up to track 'origin/main'.1668pytest-impure> branch 'update-flake-utils-my-suffix' set up to track 'origin/main'.1669pytest-impure> HEAD is now at 9bb82d8 Initial commit1670pytest-impure> ----------------------------- Captured stderr call -----------------------------1671pytest-impure> hint: Using 'master' as the name for the initial branch. This default branch name1672pytest-impure> hint: will change to "main" in Git 3.0. To configure the initial branch name1673pytest-impure> hint: to use in all of your new repositories, which will suppress this warning,1674pytest-impure> hint: call:1675pytest-impure> hint:1676pytest-impure> hint: git config --global init.defaultBranch <name>1677pytest-impure> hint:1678pytest-impure> hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and1679pytest-impure> hint: 'development'. The just-created branch can be renamed via this command:1680pytest-impure> hint:1681pytest-impure> hint: git branch -m <name>1682pytest-impure> hint:1683pytest-impure> hint: Disable this message with "git config set advice.defaultBranchName false"1684pytest-impure> To /build/pytest-of-nixbld/pytest-0/remote-test_branch_suffix0.git1685pytest-impure> * [new branch] main -> main1686pytest-impure> From /build/pytest-of-nixbld/pytest-0/remote-test_branch_suffix01687pytest-impure> * branch main -> FETCH_HEAD1688pytest-impure> Preparing worktree (new branch 'update-flake-utils-my-suffix')1689pytest-impure> ------------------------------ Captured log call -------------------------------1690pytest-impure> ERROR update_flake_inputs.flake_service:flake_service.py:223 Failed to update flake input flake-utils in flake.nix. Exit code: 11691pytest-impure> Stdout: No stdout output1692pytest-impure> Stderr: warning: you don't have Internet access; disabling some network-dependent features1693pytest-impure> error:1694pytest-impure> … while updating the lock file of flake 'git+file:///build/flake-update-2yju5t7s/update-flake-utils-my-suffix?ref=refs/heads/update-flake-utils-my-suffix&rev=9bb82d891bb38b360c0c2b9f2a1a396a258e9dd8&shallow=1'1695pytest-impure> 1696pytest-impure> … while updating the flake input 'flake-utils'1697pytest-impure> 1698pytest-impure> … while fetching the input 'github:numtide/flake-utils'1699pytest-impure> 1700pytest-impure> error: unable to download 'https://api.github.com/repos/numtide/flake-utils/commits/HEAD': Could not resolve hostname (6) Could not resolve host: api.github.com1701pytest-impure> Traceback (most recent call last):1702pytest-impure> File "/build/src/src/update_flake_inputs/flake_service.py", line 191, in update_flake_input1703pytest-impure> result = subprocess.run(1704pytest-impure> [1705pytest-impure> ...<10 lines>...1706pytest-impure> check=True,1707pytest-impure> )1708pytest-impure> File "/nix/store/6xbk6d4rk2dc9c3kbdx0rkvn2knfqcmp-python3-3.13.13-env/lib/python3.13/subprocess.py", line 577, in run1709pytest-impure> raise CalledProcessError(retcode, process.args,1710pytest-impure> output=stdout, stderr=stderr)1711pytest-impure> subprocess.CalledProcessError: Command '['nix', 'flake', 'update', '--flake', 'git+file:///build/flake-update-2yju5t7s/update-flake-utils-my-suffix?shallow=1', 'flake-utils']' returned non-zero exit status 1.1712pytest-impure> ERROR update_flake_inputs.cli:cli.py:259 Failed to update input flake-utils in flake.nix1713pytest-impure> Traceback (most recent call last):1714pytest-impure> File "/build/src/src/update_flake_inputs/flake_service.py", line 191, in update_flake_input1715pytest-impure> result = subprocess.run(1716pytest-impure> [1717pytest-impure> ...<10 lines>...1718pytest-impure> check=True,1719pytest-impure> )1720pytest-impure> File "/nix/store/6xbk6d4rk2dc9c3kbdx0rkvn2knfqcmp-python3-3.13.13-env/lib/python3.13/subprocess.py", line 577, in run1721pytest-impure> raise CalledProcessError(retcode, process.args,1722pytest-impure> output=stdout, stderr=stderr)1723pytest-impure> subprocess.CalledProcessError: Command '['nix', 'flake', 'update', '--flake', 'git+file:///build/flake-update-2yju5t7s/update-flake-utils-my-suffix?shallow=1', 'flake-utils']' returned non-zero exit status 1.1724pytest-impure> 1725pytest-impure> The above exception was the direct cause of the following exception:1726pytest-impure> 1727pytest-impure> Traceback (most recent call last):1728pytest-impure> File "/build/src/src/update_flake_inputs/cli.py", line 223, in process_flake_updates1729pytest-impure> flake_service.update_flake_input(1730pytest-impure> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^1731pytest-impure> input_name,1732pytest-impure> ^^^^^^^^^^^1733pytest-impure> flake.file_path,1734pytest-impure> ^^^^^^^^^^^^^^^^1735pytest-impure> str(worktree_path),1736pytest-impure> ^^^^^^^^^^^^^^^^^^^1737pytest-impure> )1738pytest-impure> ^1739pytest-impure> File "/build/src/src/update_flake_inputs/flake_service.py", line 235, in update_flake_input1740pytest-impure> raise FlakeServiceError(msg) from e1741pytest-impure> update_flake_inputs.exceptions.FlakeServiceError: Failed to update flake input flake-utils in flake.nix: Command '['nix', 'flake', 'update', '--flake', 'git+file:///build/flake-update-2yju5t7s/update-flake-utils-my-suffix?shallow=1', 'flake-utils']' returned non-zero exit status 1.1742pytest-impure> Stderr: warning: you don't have Internet access; disabling some network-dependent features1743pytest-impure> error:1744pytest-impure> … while updating the lock file of flake 'git+file:///build/flake-update-2yju5t7s/update-flake-utils-my-suffix?ref=refs/heads/update-flake-utils-my-suffix&rev=9bb82d891bb38b360c0c2b9f2a1a396a258e9dd8&shallow=1'1745pytest-impure> 1746pytest-impure> … while updating the flake input 'flake-utils'1747pytest-impure> 1748pytest-impure> … while fetching the input 'github:numtide/flake-utils'1749pytest-impure> 1750pytest-impure> error: unable to download 'https://api.github.com/repos/numtide/flake-utils/commits/HEAD': Could not resolve hostname (6) Could not resolve host: api.github.com1751pytest-impure> ____ TestProcessFlakeUpdates.test_fails_at_end_when_individual_input_fails _____1752pytest-impure> 1753pytest-impure> self = <tests.test_process_flake_updates.TestProcessFlakeUpdates object at 0x7ffff63328b0>1754pytest-impure> tmp_path = PosixPath('/build/pytest-of-nixbld/pytest-0/test_fails_at_end_when_individ0')1755pytest-impure> fixtures_path = PosixPath('/build/src/tests/fixtures')1756pytest-impure> 1757pytest-impure> @pytest.mark.impure1758pytest-impure> def test_fails_at_end_when_individual_input_fails(1759pytest-impure> self,1760pytest-impure> tmp_path: Path,1761pytest-impure> fixtures_path: Path,1762pytest-impure> ) -> None:1763pytest-impure> """Test that the action continues updating other inputs but fails at the end."""1764pytest-impure> flake_content = """{1765pytest-impure> inputs = {1766pytest-impure> flake-utils.url = "github:numtide/flake-utils";1767pytest-impure> };1768pytest-impure> 1769pytest-impure> outputs = { self, flake-utils }: {1770pytest-impure> # Test flake with updatable input1771pytest-impure> };1772pytest-impure> }"""1773pytest-impure> 1774pytest-impure> (tmp_path / "flake.nix").write_text(flake_content)1775pytest-impure> 1776pytest-impure> shutil.copy(1777pytest-impure> fixtures_path / "minimal" / "flake.lock",1778pytest-impure> tmp_path / "flake.lock",1779pytest-impure> )1780pytest-impure> 1781pytest-impure> _setup_git_repo(tmp_path)1782pytest-impure> 1783pytest-impure> original_cwd = Path.cwd()1784pytest-impure> os.chdir(tmp_path)1785pytest-impure> 1786pytest-impure> try:1787pytest-impure> # FailingFlakeService injects "bad-input" during discovery and1788pytest-impure> # raises when asked to update it, simulating a 403 or dead ref1789pytest-impure> flake_service = FailingFlakeService(fail_inputs=["bad-input"])1790pytest-impure> test_gitea_service = MockGiteaService()1791pytest-impure> 1792pytest-impure> with pytest.raises(UpdateFlakeInputsError, match="Failed to process 1 input"):1793pytest-impure> > process_flake_updates(1794pytest-impure> flake_service,1795pytest-impure> test_gitea_service,1796pytest-impure> "",1797pytest-impure> "main",1798pytest-impure> "",1799pytest-impure> auto_merge=False,1800pytest-impure> )1801pytest-impure> 1802pytest-impure> tests/test_process_flake_updates.py:597: 1803pytest-impure> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 1804pytest-impure> 1805pytest-impure> flake_service = <tests.test_process_flake_updates.FailingFlakeService object at 0x7ffff664acf0>1806pytest-impure> gitea_service = MockGiteaService(api_url='https://gitea.example.com', token='test-token', owner='test-owner', repo='test-repo', git_au...tions[bot]', git_committer_email='gitea-actions[bot]@noreply.gitea.io', merge_style='default', pr_creation_attempts=[])1807pytest-impure> exclude_patterns = '', base_branch = 'main', branch_suffix = ''1808pytest-impure> 1809pytest-impure> def process_flake_updates( # noqa: PLR09131810pytest-impure> flake_service: FlakeService,1811pytest-impure> gitea_service: GiteaService,1812pytest-impure> exclude_patterns: str,1813pytest-impure> base_branch: str,1814pytest-impure> branch_suffix: str,1815pytest-impure> *,1816pytest-impure> auto_merge: bool,1817pytest-impure> ) -> None:1818pytest-impure> """Process all flake updates.1819pytest-impure> 1820pytest-impure> Args:1821pytest-impure> flake_service: Flake service instance1822pytest-impure> gitea_service: Gitea service instance1823pytest-impure> exclude_patterns: Patterns to exclude1824pytest-impure> base_branch: Base branch for PRs1825pytest-impure> branch_suffix: Optional suffix to append to branch names1826pytest-impure> auto_merge: Whether to automatically merge PRs1827pytest-impure> 1828pytest-impure> """1829pytest-impure> # Discover flake files1830pytest-impure> flakes = flake_service.discover_flake_files(exclude_patterns)1831pytest-impure> if not flakes:1832pytest-impure> logger.info("No flake files found")1833pytest-impure> return1834pytest-impure> 1835pytest-impure> logger.info("Found %d flake files to process", len(flakes))1836pytest-impure> 1837pytest-impure> failed_inputs: list[str] = []1838pytest-impure> 1839pytest-impure> # Process each flake1840pytest-impure> for flake in flakes:1841pytest-impure> logger.info("Processing flake: %s", flake.file_path)1842pytest-impure> logger.info("Inputs to update: %s", ", ".join(flake.inputs))1843pytest-impure> 1844pytest-impure> # Don't include '.' for root directory1845pytest-impure> parent_path = Path(flake.file_path).parent1846pytest-impure> parent_suffix = "" if parent_path == Path() else f" in {parent_path}"1847pytest-impure> parent_branch = "" if parent_path == Path() else f"-{parent_path}"1848pytest-impure> suffix = branch_suffix.strip().replace("/", "-").strip("-")1849pytest-impure> 1850pytest-impure> # Update each input1851pytest-impure> for input_name in flake.inputs:1852pytest-impure> try:1853pytest-impure> branch_name = f"update{parent_branch}-{input_name}"1854pytest-impure> branch_name = branch_name.replace("/", "-").strip("-")1855pytest-impure> if suffix:1856pytest-impure> branch_name = f"{branch_name}-{suffix}"1857pytest-impure> 1858pytest-impure> logger.info(1859pytest-impure> "Updating input %s in %s (branch: %s)",1860pytest-impure> input_name,1861pytest-impure> flake.file_path,1862pytest-impure> branch_name,1863pytest-impure> )1864pytest-impure> 1865pytest-impure> # Create worktree and update input1866pytest-impure> with gitea_service.worktree(branch_name, base_branch) as worktree_path:1867pytest-impure> # Update the input1868pytest-impure> flake_service.update_flake_input(1869pytest-impure> input_name,1870pytest-impure> flake.file_path,1871pytest-impure> str(worktree_path),1872pytest-impure> )1873pytest-impure> 1874pytest-impure> # Commit changes1875pytest-impure> commit_message = f"Update {input_name}{parent_suffix}"1876pytest-impure> if gitea_service.commit_changes(1877pytest-impure> branch_name,1878pytest-impure> commit_message,1879pytest-impure> worktree_path,1880pytest-impure> ):1881pytest-impure> # Create pull request1882pytest-impure> pr_title = commit_message1883pytest-impure> pr_body = (1884pytest-impure> f"This PR updates the `{input_name}` input "1885pytest-impure> f"in `{flake.file_path}`.\n\n"1886pytest-impure> "Generated by update-flake-inputs action."1887pytest-impure> )1888pytest-impure> gitea_service.create_pull_request(1889pytest-impure> branch_name,1890pytest-impure> base_branch,1891pytest-impure> pr_title,1892pytest-impure> pr_body,1893pytest-impure> auto_merge=auto_merge,1894pytest-impure> )1895pytest-impure> else:1896pytest-impure> logger.info(1897pytest-impure> "No changes for input %s in %s",1898pytest-impure> input_name,1899pytest-impure> flake.file_path,1900pytest-impure> )1901pytest-impure> gitea_service.delete_branch(branch_name)1902pytest-impure> 1903pytest-impure> except Exception:1904pytest-impure> logger.exception(1905pytest-impure> "Failed to update input %s in %s",1906pytest-impure> input_name,1907pytest-impure> flake.file_path,1908pytest-impure> )1909pytest-impure> failed_inputs.append(f"{input_name} in {flake.file_path}")1910pytest-impure> 1911pytest-impure> if failed_inputs:1912pytest-impure> msg = f"Failed to process {len(failed_inputs)} input(s): {', '.join(failed_inputs)}"1913pytest-impure> > raise UpdateFlakeInputsError(msg)1914pytest-impure> E update_flake_inputs.exceptions.UpdateFlakeInputsError: Failed to process 2 input(s): bad-input in flake.nix, flake-utils in flake.nix1915pytest-impure> 1916pytest-impure> src/update_flake_inputs/cli.py:268: UpdateFlakeInputsError1917pytest-impure> 1918pytest-impure> During handling of the above exception, another exception occurred:1919pytest-impure> 1920pytest-impure> self = <tests.test_process_flake_updates.TestProcessFlakeUpdates object at 0x7ffff63328b0>1921pytest-impure> tmp_path = PosixPath('/build/pytest-of-nixbld/pytest-0/test_fails_at_end_when_individ0')1922pytest-impure> fixtures_path = PosixPath('/build/src/tests/fixtures')1923pytest-impure> 1924pytest-impure> @pytest.mark.impure1925pytest-impure> def test_fails_at_end_when_individual_input_fails(1926pytest-impure> self,1927pytest-impure> tmp_path: Path,1928pytest-impure> fixtures_path: Path,1929pytest-impure> ) -> None:1930pytest-impure> """Test that the action continues updating other inputs but fails at the end."""1931pytest-impure> flake_content = """{1932pytest-impure> inputs = {1933pytest-impure> flake-utils.url = "github:numtide/flake-utils";1934pytest-impure> };1935pytest-impure> 1936pytest-impure> outputs = { self, flake-utils }: {1937pytest-impure> # Test flake with updatable input1938pytest-impure> };1939pytest-impure> }"""1940pytest-impure> 1941pytest-impure> (tmp_path / "flake.nix").write_text(flake_content)1942pytest-impure> 1943pytest-impure> shutil.copy(1944pytest-impure> fixtures_path / "minimal" / "flake.lock",1945pytest-impure> tmp_path / "flake.lock",1946pytest-impure> )1947pytest-impure> 1948pytest-impure> _setup_git_repo(tmp_path)1949pytest-impure> 1950pytest-impure> original_cwd = Path.cwd()1951pytest-impure> os.chdir(tmp_path)1952pytest-impure> 1953pytest-impure> try:1954pytest-impure> # FailingFlakeService injects "bad-input" during discovery and1955pytest-impure> # raises when asked to update it, simulating a 403 or dead ref1956pytest-impure> flake_service = FailingFlakeService(fail_inputs=["bad-input"])1957pytest-impure> test_gitea_service = MockGiteaService()1958pytest-impure> 1959pytest-impure> > with pytest.raises(UpdateFlakeInputsError, match="Failed to process 1 input"):1960pytest-impure> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^1961pytest-impure> E AssertionError: Regex pattern did not match.1962pytest-impure> E Expected regex: 'Failed to process 1 input'1963pytest-impure> E Actual message: 'Failed to process 2 input(s): bad-input in flake.nix, flake-utils in flake.nix'1964pytest-impure> 1965pytest-impure> tests/test_process_flake_updates.py:596: AssertionError1966pytest-impure> ----------------------------- Captured stdout call -----------------------------1967pytest-impure> Initialized empty Git repository in /build/pytest-of-nixbld/pytest-0/test_fails_at_end_when_individ0/.git/1968pytest-impure> [main (root-commit) 07a18c9] Initial commit1969pytest-impure> 2 files changed, 53 insertions(+)1970pytest-impure> create mode 100644 flake.lock1971pytest-impure> create mode 100644 flake.nix1972pytest-impure> Initialized empty Git repository in /build/pytest-of-nixbld/pytest-0/remote-test_fails_at_end_when_individ0.git/1973pytest-impure> branch 'main' set up to track 'origin/main'.1974pytest-impure> branch 'update-bad-input' set up to track 'origin/main'.1975pytest-impure> HEAD is now at 07a18c9 Initial commit1976pytest-impure> branch 'update-flake-utils' set up to track 'origin/main'.1977pytest-impure> HEAD is now at 07a18c9 Initial commit1978pytest-impure> ----------------------------- Captured stderr call -----------------------------1979pytest-impure> hint: Using 'master' as the name for the initial branch. This default branch name1980pytest-impure> hint: will change to "main" in Git 3.0. To configure the initial branch name1981pytest-impure> hint: to use in all of your new repositories, which will suppress this warning,1982pytest-impure> hint: call:1983pytest-impure> hint:1984pytest-impure> hint: git config --global init.defaultBranch <name>1985pytest-impure> hint:1986pytest-impure> hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and1987pytest-impure> hint: 'development'. The just-created branch can be renamed via this command:1988pytest-impure> hint:1989pytest-impure> hint: git branch -m <name>1990pytest-impure> hint:1991pytest-impure> hint: Disable this message with "git config set advice.defaultBranchName false"1992pytest-impure> To /build/pytest-of-nixbld/pytest-0/remote-test_fails_at_end_when_individ0.git1993pytest-impure> * [new branch] main -> main1994pytest-impure> From /build/pytest-of-nixbld/pytest-0/remote-test_fails_at_end_when_individ01995pytest-impure> * branch main -> FETCH_HEAD1996pytest-impure> Preparing worktree (new branch 'update-bad-input')1997pytest-impure> From /build/pytest-of-nixbld/pytest-0/remote-test_fails_at_end_when_individ01998pytest-impure> * branch main -> FETCH_HEAD1999pytest-impure> Preparing worktree (new branch 'update-flake-utils')2000pytest-impure> ------------------------------ Captured log call -------------------------------2001pytest-impure> ERROR update_flake_inputs.cli:cli.py:259 Failed to update input bad-input in flake.nix2002pytest-impure> Traceback (most recent call last):2003pytest-impure> File "/build/src/src/update_flake_inputs/cli.py", line 223, in process_flake_updates2004pytest-impure> flake_service.update_flake_input(2005pytest-impure> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^2006pytest-impure> input_name,2007pytest-impure> ^^^^^^^^^^^2008pytest-impure> flake.file_path,2009pytest-impure> ^^^^^^^^^^^^^^^^2010pytest-impure> str(worktree_path),2011pytest-impure> ^^^^^^^^^^^^^^^^^^^2012pytest-impure> )2013pytest-impure> ^2014pytest-impure> File "/build/src/tests/test_process_flake_updates.py", line 635, in update_flake_input2015pytest-impure> raise FlakeServiceError(msg)2016pytest-impure> update_flake_inputs.exceptions.FlakeServiceError: Simulated failure updating bad-input2017pytest-impure> ERROR update_flake_inputs.flake_service:flake_service.py:223 Failed to update flake input flake-utils in flake.nix. Exit code: 12018pytest-impure> Stdout: No stdout output2019pytest-impure> Stderr: warning: you don't have Internet access; disabling some network-dependent features2020pytest-impure> error:2021pytest-impure> … while updating the lock file of flake 'git+file:///build/flake-update-j4a92_6f/update-flake-utils?ref=refs/heads/update-flake-utils&rev=07a18c94dddb80abac537c6eb4cdf7b5a5dc1ae2&shallow=1'2022pytest-impure> 2023pytest-impure> … while updating the flake input 'flake-utils'2024pytest-impure> 2025pytest-impure> … while fetching the input 'github:numtide/flake-utils'2026pytest-impure> 2027pytest-impure> error: unable to download 'https://api.github.com/repos/numtide/flake-utils/commits/HEAD': Could not resolve hostname (6) Could not resolve host: api.github.com2028pytest-impure> Traceback (most recent call last):2029pytest-impure> File "/build/src/src/update_flake_inputs/flake_service.py", line 191, in update_flake_input2030pytest-impure> result = subprocess.run(2031pytest-impure> [2032pytest-impure> ...<10 lines>...2033pytest-impure> check=True,2034pytest-impure> )2035pytest-impure> File "/nix/store/6xbk6d4rk2dc9c3kbdx0rkvn2knfqcmp-python3-3.13.13-env/lib/python3.13/subprocess.py", line 577, in run2036pytest-impure> raise CalledProcessError(retcode, process.args,2037pytest-impure> output=stdout, stderr=stderr)2038pytest-impure> subprocess.CalledProcessError: Command '['nix', 'flake', 'update', '--flake', 'git+file:///build/flake-update-j4a92_6f/update-flake-utils?shallow=1', 'flake-utils']' returned non-zero exit status 1.2039pytest-impure> ERROR update_flake_inputs.cli:cli.py:259 Failed to update input flake-utils in flake.nix2040pytest-impure> Traceback (most recent call last):2041pytest-impure> File "/build/src/src/update_flake_inputs/flake_service.py", line 191, in update_flake_input2042pytest-impure> result = subprocess.run(2043pytest-impure> [2044pytest-impure> ...<10 lines>...2045pytest-impure> check=True,2046pytest-impure> )2047pytest-impure> File "/nix/store/6xbk6d4rk2dc9c3kbdx0rkvn2knfqcmp-python3-3.13.13-env/lib/python3.13/subprocess.py", line 577, in run2048pytest-impure> raise CalledProcessError(retcode, process.args,2049pytest-impure> output=stdout, stderr=stderr)2050pytest-impure> subprocess.CalledProcessError: Command '['nix', 'flake', 'update', '--flake', 'git+file:///build/flake-update-j4a92_6f/update-flake-utils?shallow=1', 'flake-utils']' returned non-zero exit status 1.2051pytest-impure> 2052pytest-impure> The above exception was the direct cause of the following exception:2053pytest-impure> 2054pytest-impure> Traceback (most recent call last):2055pytest-impure> File "/build/src/src/update_flake_inputs/cli.py", line 223, in process_flake_updates2056pytest-impure> flake_service.update_flake_input(2057pytest-impure> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^2058pytest-impure> input_name,2059pytest-impure> ^^^^^^^^^^^2060pytest-impure> flake.file_path,2061pytest-impure> ^^^^^^^^^^^^^^^^2062pytest-impure> str(worktree_path),2063pytest-impure> ^^^^^^^^^^^^^^^^^^^2064pytest-impure> )2065pytest-impure> ^2066pytest-impure> File "/build/src/tests/test_process_flake_updates.py", line 636, in update_flake_input2067pytest-impure> super().update_flake_input(input_name, flake_file, work_dir)2068pytest-impure> ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^2069pytest-impure> File "/build/src/src/update_flake_inputs/flake_service.py", line 235, in update_flake_input2070pytest-impure> raise FlakeServiceError(msg) from e2071pytest-impure> update_flake_inputs.exceptions.FlakeServiceError: Failed to update flake input flake-utils in flake.nix: Command '['nix', 'flake', 'update', '--flake', 'git+file:///build/flake-update-j4a92_6f/update-flake-utils?shallow=1', 'flake-utils']' returned non-zero exit status 1.2072pytest-impure> Stderr: warning: you don't have Internet access; disabling some network-dependent features2073pytest-impure> error:2074pytest-impure> … while updating the lock file of flake 'git+file:///build/flake-update-j4a92_6f/update-flake-utils?ref=refs/heads/update-flake-utils&rev=07a18c94dddb80abac537c6eb4cdf7b5a5dc1ae2&shallow=1'2075pytest-impure> 2076pytest-impure> … while updating the flake input 'flake-utils'2077pytest-impure> 2078pytest-impure> … while fetching the input 'github:numtide/flake-utils'2079pytest-impure> 2080pytest-impure> error: unable to download 'https://api.github.com/repos/numtide/flake-utils/commits/HEAD': Could not resolve hostname (6) Could not resolve host: api.github.com2081pytest-impure> =========================== short test summary info ============================2082pytest-impure> FAILED tests/test_flake_service.py::TestFlakeService::test_update_flake_input2083pytest-impure> FAILED tests/test_flake_service.py::TestFlakeService::test_update_subflake_input2084pytest-impure> FAILED tests/test_process_flake_updates.py::TestProcessFlakeUpdates::test_with_updatable_flake_input2085pytest-impure> FAILED tests/test_process_flake_updates.py::TestProcessFlakeUpdates::test_worktree_based_on_base_branch_not_head2086pytest-impure> FAILED tests/test_process_flake_updates.py::TestProcessFlakeUpdates::test_custom_git_author_committer2087pytest-impure> FAILED tests/test_process_flake_updates.py::TestProcessFlakeUpdates::test_branch_suffix2088pytest-impure> FAILED tests/test_process_flake_updates.py::TestProcessFlakeUpdates::test_fails_at_end_when_individual_input_fails2089pytest-impure> 7 failed, 16 passed in 73.50s (0:01:13)2090error: Cannot build '/nix/store/rk1g551dlhdg23nwqfg7yxcldak3fjcb-pytest-impure.drv'.2091 Reason: builder failed with exit code 1.2092 Last 25 log lines:2093 > ^2094 > File "/build/src/tests/test_process_flake_updates.py", line 636, in update_flake_input2095 > super().update_flake_input(input_name, flake_file, work_dir)2096 > ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^2097 > File "/build/src/src/update_flake_inputs/flake_service.py", line 235, in update_flake_input2098 > raise FlakeServiceError(msg) from e2099 > update_flake_inputs.exceptions.FlakeServiceError: Failed to update flake input flake-utils in flake.nix: Command '['nix', 'flake', 'update', '--flake', 'git+file:///build/flake-update-j4a92_6f/update-flake-utils?shallow=1', 'flake-utils']' returned non-zero exit status 1.2100 > Stderr: warning: you don't have Internet access; disabling some network-dependent features2101 > error:2102 > … while updating the lock file of flake 'git+file:///build/flake-update-j4a92_6f/update-flake-utils?ref=refs/heads/update-flake-utils&rev=07a18c94dddb80abac537c6eb4cdf7b5a5dc1ae2&shallow=1'2103 >2104 > … while updating the flake input 'flake-utils'2105 >2106 > … while fetching the input 'github:numtide/flake-utils'2107 >2108 > error: unable to download 'https://api.github.com/repos/numtide/flake-utils/commits/HEAD': Could not resolve hostname (6) Could not resolve host: api.github.com2109 > =========================== short test summary info ============================2110 > FAILED tests/test_flake_service.py::TestFlakeService::test_update_flake_input2111 > FAILED tests/test_flake_service.py::TestFlakeService::test_update_subflake_input2112 > FAILED tests/test_process_flake_updates.py::TestProcessFlakeUpdates::test_with_updatable_flake_input2113 > FAILED tests/test_process_flake_updates.py::TestProcessFlakeUpdates::test_worktree_based_on_base_branch_not_head2114 > FAILED tests/test_process_flake_updates.py::TestProcessFlakeUpdates::test_custom_git_author_committer2115 > FAILED tests/test_process_flake_updates.py::TestProcessFlakeUpdates::test_branch_suffix2116 > FAILED tests/test_process_flake_updates.py::TestProcessFlakeUpdates::test_fails_at_end_when_individual_input_fails2117 > 7 failed, 16 passed in 73.50s (0:01:13)2118 For full logs, run:2119 nix log /nix/store/rk1g551dlhdg23nwqfg7yxcldak3fjcb-pytest-impure.drv2120error: build of resolved derivation '/nix/store/rk1g551dlhdg23nwqfg7yxcldak3fjcb-pytest-impure.drv' failed212121222123nixbot: transient error detected, retrying once21242125this derivation will be built:2126 /nix/store/4i8pjvmjr95sq3cxqc4fnrlyz2n3dlcd-pytest-impure.drv2127building '/nix/store/rk1g551dlhdg23nwqfg7yxcldak3fjcb-pytest-impure.drv'2128pytest-impure> tribuchet: building on jamie