Coverage for webapp/publisher/snaps/builds.py : 74%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1from enum import Enum
4class StoreFrontBuildState(Enum):
5 NEVER_BUILT = "never_built"
6 BUILDING_SOON = "building_soon"
7 WONT_RELEASE = "wont_release"
8 RELEASED = "released"
9 RELEASE_FAILED = "release_failed"
10 RELEASING_SOON = "releasing_soon"
11 IN_PROGRESS = "in_progress"
12 FAILED_TO_BUILD = "failed_to_build"
13 CANCELLED = "cancelled"
14 UNKNOWN = "unknown"
17class LaunchpadBuildState(Enum):
18 NEEDS_BUILD = "Needs building"
19 FULLY_BUILT = "Successfully built"
20 FAILED_BUILD = "Failed to build"
21 MANUALDEPWAIT = "Dependency wait"
22 CHROOTWAIT = "Chroot problem"
23 SUPERSEDED = "Build for superseded Source"
24 BUILDING = "Currently building"
25 FAILED_UPLOAD = "Failed to upload"
26 UPLOADING = "Uploading build"
27 CANCELLING = "Cancelling build"
28 CANCELLED = "Cancelled build"
31class LaunchpadStoreUploadState(Enum):
32 UNSCHEDULED = "Unscheduled"
33 PENDING = "Pending"
34 FAILED_UPLOAD = "Failed to upload"
35 FAILED_RELEASE = "Failed to release to channels"
36 UPLOADED = "Uploaded"
39def build_link(bsi_url, snap, build):
40 """Builds the link to the build page"""
41 build_id = build["self_link"].split("/")[-1]
43 # Remove GitHub hostname & split owner/repo
44 owner, repo = snap["git_repository_url"][19:].split("/")
46 return f"{bsi_url}/user/{owner}/{repo}/{build_id}"
49def _map_upload_state(upload_state):
50 """Returns a user facing status based on
51 the status of the snap's upload to the store.
52 """
53 upload_state = LaunchpadStoreUploadState(upload_state)
54 if upload_state == LaunchpadStoreUploadState.UNSCHEDULED:
55 return StoreFrontBuildState.WONT_RELEASE.value
57 elif upload_state == LaunchpadStoreUploadState.PENDING:
58 return StoreFrontBuildState.RELEASING_SOON.value
60 elif (
61 upload_state == LaunchpadStoreUploadState.FAILED_UPLOAD
62 or upload_state == LaunchpadStoreUploadState.FAILED_RELEASE
63 ):
64 return StoreFrontBuildState.RELEASE_FAILED.value
66 elif upload_state == LaunchpadStoreUploadState.UPLOADED:
67 return StoreFrontBuildState.RELEASED.value
69 return StoreFrontBuildState.UNKNOWN.value
72def map_build_and_upload_states(build_state, upload_state):
73 """Returns a user facing status based on the LP
74 build state and the status of the snap's
75 upload to the store.
76 """
77 build_state = LaunchpadBuildState(build_state)
79 if build_state == LaunchpadBuildState.NEEDS_BUILD:
80 return StoreFrontBuildState.BUILDING_SOON.value
82 elif build_state == LaunchpadBuildState.FULLY_BUILT:
83 return _map_upload_state(upload_state)
85 elif build_state == LaunchpadBuildState.BUILDING:
86 return StoreFrontBuildState.IN_PROGRESS.value
88 elif build_state == LaunchpadBuildState.UPLOADING:
89 return StoreFrontBuildState.IN_PROGRESS.value
91 elif build_state in [
92 LaunchpadBuildState.CANCELLING,
93 LaunchpadBuildState.CANCELLED,
94 ]:
95 return StoreFrontBuildState.CANCELLED.value
97 elif build_state in [
98 LaunchpadBuildState.FAILED_BUILD,
99 LaunchpadBuildState.MANUALDEPWAIT,
100 LaunchpadBuildState.CHROOTWAIT,
101 LaunchpadBuildState.SUPERSEDED,
102 LaunchpadBuildState.FAILED_UPLOAD,
103 ]:
104 return StoreFrontBuildState.FAILED_TO_BUILD.value
106 return StoreFrontBuildState.UNKNOWN.value
109def map_snap_build_status(snap_build_statuses):
110 """Returns a user facing status based on the LP
111 build state and the status of the snap's
112 upload to the store.
113 """
114 mapped_arch_statuses = set()
116 for arch_statuses in snap_build_statuses.values():
117 mapped_status = map_build_and_upload_states(
118 arch_statuses["buildstate"], arch_statuses["store_upload_status"]
119 )
121 # Return instantly a failure status if one arch is failing
122 if mapped_status in [
123 StoreFrontBuildState.NEVER_BUILT.value,
124 StoreFrontBuildState.WONT_RELEASE.value,
125 StoreFrontBuildState.RELEASE_FAILED.value,
126 StoreFrontBuildState.FAILED_TO_BUILD.value,
127 StoreFrontBuildState.CANCELLED.value,
128 ]:
129 return mapped_status
131 mapped_arch_statuses.add(mapped_status)
133 # All the archs have the same status
134 if len(mapped_arch_statuses) == 1:
135 return mapped_arch_statuses.pop()
137 # List of the non-failure status in the preferred order to return
138 positive_statuses = [
139 StoreFrontBuildState.BUILDING_SOON.value,
140 StoreFrontBuildState.IN_PROGRESS.value,
141 StoreFrontBuildState.RELEASING_SOON.value,
142 StoreFrontBuildState.RELEASED.value,
143 ]
145 for status in positive_statuses:
146 if status in mapped_arch_statuses:
147 return status
149 return StoreFrontBuildState.UNKNOWN.value