gowalk-cicd 1.0.8 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -206,15 +206,23 @@ Provisioning profile "CI-com.example.app" doesn't include the App Attest capabil
|
|
|
206
206
|
|
|
207
207
|
Before creating a profile, the action reads the target's
|
|
208
208
|
`CODE_SIGN_ENTITLEMENTS` plist and enables the matching capabilities on the App
|
|
209
|
-
ID — Push Notifications,
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
209
|
+
ID — Push Notifications, Associated Domains, HealthKit, SiriKit, HomeKit,
|
|
210
|
+
network extensions and the other plain on/off toggles. Whenever the App ID was
|
|
211
|
+
missing something it regenerates the profile rather than reusing the cached
|
|
212
|
+
one, which was issued before the capability existed.
|
|
213
|
+
|
|
214
|
+
Two classes of capability are **not** enabled automatically, and each gets a
|
|
215
|
+
`::warning::` naming what was seen:
|
|
216
|
+
|
|
217
|
+
- **Values the action cannot infer** — App Groups, iCloud containers, Apple Pay
|
|
218
|
+
merchant IDs, Wallet pass types, Data Protection. Configure these on the App
|
|
219
|
+
ID yourself.
|
|
220
|
+
- **App Attest** — a real App ID capability in the developer portal, but absent
|
|
221
|
+
from the ASC API's `capabilityType` enum, so *no* API call can turn it on.
|
|
222
|
+
Any app using Firebase App Check's `AppAttestProvider` must have App Attest
|
|
223
|
+
ticked once by hand under **Certificates, Identifiers & Profiles → Identifiers
|
|
224
|
+
→ <your App ID>**. Until then the archive fails with `Provisioning profile
|
|
225
|
+
"CI-<bundle>" doesn't include the App Attest capability`.
|
|
218
226
|
|
|
219
227
|
## AI metadata auto-fill
|
|
220
228
|
|
package/action/.daemux-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.0.
|
|
1
|
+
1.0.9
|
|
@@ -41,7 +41,6 @@ _API_FAILURES = (Exception, SystemExit)
|
|
|
41
41
|
# capability at all.
|
|
42
42
|
CAPABILITY_BY_ENTITLEMENT = {
|
|
43
43
|
"aps-environment": "PUSH_NOTIFICATIONS",
|
|
44
|
-
"com.apple.developer.devicecheck.appattest-environment": "APP_ATTEST",
|
|
45
44
|
"com.apple.developer.associated-domains": "ASSOCIATED_DOMAINS",
|
|
46
45
|
"com.apple.developer.applesignin": "APPLE_ID_AUTH",
|
|
47
46
|
"com.apple.developer.networking.wifi-info": "ACCESS_WIFI_INFORMATION",
|
|
@@ -66,6 +65,14 @@ CAPABILITY_BY_ENTITLEMENT = {
|
|
|
66
65
|
# unambiguously. Enabling these blind would create a half-configured App ID,
|
|
67
66
|
# so we say what is missing and stop.
|
|
68
67
|
MANUAL_ENTITLEMENTS = {
|
|
68
|
+
# App Attest is a real App ID capability in the developer portal, but it is
|
|
69
|
+
# absent from the ASC API's capabilityType enum entirely — POSTing it
|
|
70
|
+
# returns 409 ENTITY_ERROR.ATTRIBUTE.TYPE listing the valid values, which
|
|
71
|
+
# do not include it. There is no API to turn this one on.
|
|
72
|
+
"com.apple.developer.devicecheck.appattest-environment": (
|
|
73
|
+
"App Attest, which the App Store Connect API cannot enable — tick it "
|
|
74
|
+
"on the App ID under Certificates, Identifiers & Profiles"
|
|
75
|
+
),
|
|
69
76
|
"com.apple.security.application-groups": "App Groups",
|
|
70
77
|
"com.apple.developer.icloud-container-identifiers": "iCloud",
|
|
71
78
|
"com.apple.developer.icloud-services": "iCloud",
|
|
@@ -145,9 +152,12 @@ def enable_capability(token: str, bundle_pk: str, capability: str) -> bool:
|
|
|
145
152
|
# identically from the status code alone. Surface the body: without it
|
|
146
153
|
# the run just reports a profile missing a capability we claimed to
|
|
147
154
|
# have enabled, and there is nothing in the log to explain why.
|
|
155
|
+
# Untruncated enough to show Apple's full list of valid capabilityType
|
|
156
|
+
# values, which is the only way to learn that a name is simply not
|
|
157
|
+
# API-manageable (see App Attest in MANUAL_ENTITLEMENTS).
|
|
148
158
|
print(
|
|
149
159
|
f"::warning::App Store Connect returned 409 for {capability}: "
|
|
150
|
-
f"{response.text[:
|
|
160
|
+
f"{response.text[:2000]}"
|
|
151
161
|
)
|
|
152
162
|
return False
|
|
153
163
|
print(f"Enabled {capability} on the App ID")
|
|
@@ -19,6 +19,7 @@ import capabilities
|
|
|
19
19
|
|
|
20
20
|
ENTITLEMENTS = {
|
|
21
21
|
"aps-environment": "production",
|
|
22
|
+
"com.apple.developer.associated-domains": ["applinks:gowalk.example"],
|
|
22
23
|
"com.apple.developer.devicecheck.appattest-environment": "production",
|
|
23
24
|
"keychain-access-groups": ["$(AppIdentifierPrefix)com.gowalk.form"],
|
|
24
25
|
}
|
|
@@ -46,12 +47,26 @@ class ReadEntitlementsTest(unittest.TestCase):
|
|
|
46
47
|
|
|
47
48
|
class RequiredCapabilitiesTest(unittest.TestCase):
|
|
48
49
|
def test_maps_only_known_toggles(self) -> None:
|
|
49
|
-
# keychain-access-groups needs no App ID capability at all
|
|
50
|
+
# keychain-access-groups needs no App ID capability at all, and App
|
|
51
|
+
# Attest is not in the ASC API's capabilityType enum, so neither can
|
|
52
|
+
# produce a POST.
|
|
50
53
|
self.assertEqual(
|
|
51
54
|
capabilities.required_capabilities(set(ENTITLEMENTS)),
|
|
52
|
-
{"PUSH_NOTIFICATIONS", "
|
|
55
|
+
{"PUSH_NOTIFICATIONS", "ASSOCIATED_DOMAINS"},
|
|
53
56
|
)
|
|
54
57
|
|
|
58
|
+
def test_app_attest_is_reported_not_attempted(self) -> None:
|
|
59
|
+
key = "com.apple.developer.devicecheck.appattest-environment"
|
|
60
|
+
|
|
61
|
+
self.assertNotIn(key, capabilities.CAPABILITY_BY_ENTITLEMENT)
|
|
62
|
+
self.assertIn(key, capabilities.MANUAL_ENTITLEMENTS)
|
|
63
|
+
|
|
64
|
+
with mock.patch("builtins.print") as printed:
|
|
65
|
+
capabilities.warn_about_manual_entitlements({key}, "com.gowalk.form")
|
|
66
|
+
|
|
67
|
+
messages = [c.args[0] for c in printed.call_args_list if c.args]
|
|
68
|
+
self.assertTrue(any("App Attest" in m for m in messages), messages)
|
|
69
|
+
|
|
55
70
|
def test_ignores_entitlements_with_no_capability(self) -> None:
|
|
56
71
|
self.assertEqual(
|
|
57
72
|
capabilities.required_capabilities({"get-task-allow", "com.apple.security.get-task-allow"}),
|
|
@@ -78,13 +93,13 @@ class ReconcileTest(unittest.TestCase):
|
|
|
78
93
|
changed = capabilities.reconcile("tok", "PK", "com.gowalk.form", set(ENTITLEMENTS))
|
|
79
94
|
|
|
80
95
|
self.assertTrue(changed)
|
|
81
|
-
self.assertEqual(posted, ["
|
|
96
|
+
self.assertEqual(posted, ["ASSOCIATED_DOMAINS"])
|
|
82
97
|
|
|
83
98
|
def test_no_op_when_the_app_id_already_has_everything(self) -> None:
|
|
84
99
|
listed = {
|
|
85
100
|
"data": [
|
|
86
101
|
{"attributes": {"capabilityType": "PUSH_NOTIFICATIONS"}},
|
|
87
|
-
{"attributes": {"capabilityType": "
|
|
102
|
+
{"attributes": {"capabilityType": "ASSOCIATED_DOMAINS"}},
|
|
88
103
|
]
|
|
89
104
|
}
|
|
90
105
|
with mock.patch.object(capabilities, "get_json", return_value=listed), \
|
|
@@ -107,7 +122,7 @@ class ReconcileTest(unittest.TestCase):
|
|
|
107
122
|
mock.patch.object(capabilities, "request", side_effect=fake_request):
|
|
108
123
|
capabilities.reconcile("tok", "PK", "com.gowalk.form", set(ENTITLEMENTS))
|
|
109
124
|
|
|
110
|
-
self.assertEqual(sorted(posted), ["
|
|
125
|
+
self.assertEqual(sorted(posted), ["ASSOCIATED_DOMAINS", "PUSH_NOTIFICATIONS"])
|
|
111
126
|
|
|
112
127
|
def test_regenerates_even_when_the_capability_could_not_be_enabled(self) -> None:
|
|
113
128
|
# A 409 (or any refusal) still means the cached profile was issued
|
|
@@ -119,7 +134,7 @@ class ReconcileTest(unittest.TestCase):
|
|
|
119
134
|
mock.patch.object(capabilities, "request", return_value=response):
|
|
120
135
|
changed = capabilities.reconcile(
|
|
121
136
|
"tok", "PK", "com.gowalk.form",
|
|
122
|
-
{"com.apple.developer.
|
|
137
|
+
{"com.apple.developer.associated-domains"},
|
|
123
138
|
)
|
|
124
139
|
|
|
125
140
|
self.assertTrue(changed)
|
|
@@ -132,7 +147,7 @@ class ReconcileTest(unittest.TestCase):
|
|
|
132
147
|
mock.patch("builtins.print") as printed:
|
|
133
148
|
capabilities.reconcile(
|
|
134
149
|
"tok", "PK", "com.gowalk.form",
|
|
135
|
-
{"com.apple.developer.
|
|
150
|
+
{"com.apple.developer.associated-domains"},
|
|
136
151
|
)
|
|
137
152
|
|
|
138
153
|
messages = [c.args[0] for c in printed.call_args_list if c.args]
|
|
@@ -145,7 +160,7 @@ class ReconcileTest(unittest.TestCase):
|
|
|
145
160
|
mock.patch.object(capabilities, "request", side_effect=RuntimeError("boom")):
|
|
146
161
|
changed = capabilities.reconcile(
|
|
147
162
|
"tok", "PK", "com.gowalk.form",
|
|
148
|
-
{"com.apple.developer.
|
|
163
|
+
{"com.apple.developer.associated-domains"},
|
|
149
164
|
)
|
|
150
165
|
|
|
151
166
|
self.assertTrue(changed)
|
|
@@ -159,7 +174,7 @@ class ReconcileTest(unittest.TestCase):
|
|
|
159
174
|
mock.patch.object(capabilities, "request", side_effect=SystemExit("400")):
|
|
160
175
|
changed = capabilities.reconcile(
|
|
161
176
|
"tok", "PK", "com.gowalk.form",
|
|
162
|
-
{"com.apple.developer.
|
|
177
|
+
{"com.apple.developer.associated-domains"},
|
|
163
178
|
)
|
|
164
179
|
|
|
165
180
|
self.assertTrue(changed)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
1.0.
|
|
1
|
+
1.0.9
|