(
target: str, archs: Set[str], status: Dict[str, Dict[str, str]],
running: Dict[str, bool], output_lock: Lock)
| 97 | |
| 98 | |
| 99 | def _build_snap( |
| 100 | target: str, archs: Set[str], status: Dict[str, Dict[str, str]], |
| 101 | running: Dict[str, bool], output_lock: Lock) -> bool: |
| 102 | if target == 'certbot': |
| 103 | workspace = CERTBOT_DIR |
| 104 | else: |
| 105 | workspace = join(CERTBOT_DIR, target) |
| 106 | # Init and commit git repo in workspace. This is necessary starting in core24 |
| 107 | # as "Projects must be at the top level of a git repository" |
| 108 | # https://snapcraft.io/docs/migrate-core24#remote-build |
| 109 | subprocess.run(['git', 'init'], capture_output=True, check=True, cwd=workspace) |
| 110 | subprocess.run(['git', 'add', '-A'], capture_output=True, check=True, cwd=workspace) |
| 111 | subprocess.run(['git', 'commit', '-m', 'init'], capture_output=True, check=True, cwd=workspace) |
| 112 | |
| 113 | build_success = False |
| 114 | retry = 3 |
| 115 | while retry: |
| 116 | # Let's reset the status before each build so we're not starting with |
| 117 | # old state values. |
| 118 | status[target] = {arch: '...' for arch in archs} |
| 119 | exit_code, process_output = _execute_build(target, archs, status, workspace, output_lock) |
| 120 | with output_lock: |
| 121 | print(f'Build {target} for {",".join(archs)} (attempt {4-retry}/3) ended with ' |
| 122 | f'exit code {exit_code}.') |
| 123 | |
| 124 | # This output may change, and is set by |
| 125 | # https://github.com/canonical/snapcraft/blob/8ab7fd0c8a1d3f13045bec41a6e0158c063faa9b/snapcraft/commands/remote.py#L278 |
| 126 | failed_archs = [arch for arch in archs if status[target][arch] != 'Succeeded'] |
| 127 | # If the command failed or any architecture wasn't built |
| 128 | # successfully, let's try to print all the output about the problem |
| 129 | # that we can. |
| 130 | dump_output = exit_code != 0 or failed_archs |
| 131 | if exit_code == 0 and not failed_archs: |
| 132 | # We expect to have all target snaps available, or something bad happened. |
| 133 | snaps_list = glob.glob(join(workspace, '*.snap')) |
| 134 | if not len(snaps_list) == len(archs): |
| 135 | print('Some of the expected snaps for a successful build are missing ' |
| 136 | f'(current list: {snaps_list}).') |
| 137 | dump_output = True |
| 138 | else: |
| 139 | build_success = True |
| 140 | break |
| 141 | if dump_output: |
| 142 | print(f'Dumping snapcraft remote-build output build for {target}:') |
| 143 | print('\n'.join(process_output)) |
| 144 | _dump_failed_build_logs(target, archs, status, workspace) |
| 145 | |
| 146 | # Retry the remote build if it has been interrupted (non zero status code) |
| 147 | # or if some builds have failed. |
| 148 | retry = retry - 1 |
| 149 | |
| 150 | running[target] = False |
| 151 | |
| 152 | return build_success |
| 153 | |
| 154 | |
| 155 | def _extract_state(project: str, output: str, status: Dict[str, Dict[str, str]]) -> None: |
nothing calls this directly
no test coverage detected