Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,6 @@ Local.xcconfig

# App Review contact details for Scripts/asc.py — a person's phone and email
Store/review-contact.local.json

# Python bytecode from running Scripts/asc.py
__pycache__/
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ Requires macOS 14+, and Xcode 16+ with [XcodeGen](https://github.com/yonaskolb/X
GitCleared is built from source:

```sh
git clone https://github.com/hollandcloud/cleared.git
cd cleared
git clone https://github.com/hollandcloud/gitcleared.git
cd gitcleared
make install # builds Release, copies it to /Applications, launches it
```

Expand Down
134 changes: 134 additions & 0 deletions Scripts/asc.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
Scripts/asc.py status # what ASC currently has. Run this first.
Scripts/asc.py version 1.1.1 # open a new version once the last one is on sale
Scripts/asc.py text # name, subtitle, description, keywords, URLs
Scripts/asc.py info # category and the content-rights answer
Scripts/asc.py pricing # free, everywhere but China mainland (one-time)
# release notes come from
# release_notes-<PLATFORM>.txt where present
Scripts/asc.py screenshots # upload Store/screenshots/<platform>/
Expand Down Expand Up @@ -370,6 +372,133 @@ def push_text() -> None:
print(f" {platform}: {', '.join(attributes)}{note}")


def read_meta(name: str) -> str | None:
"""A field that is not per-language, from Store/metadata/<name>.txt."""
path = STORE / "metadata" / f"{name}.txt"
return path.read_text().strip() if path.exists() else None


def push_info() -> None:
"""App Information that is not per-language: the category, and the content-rights answer.

Both hang off the app rather than a version. The category is set on whichever
`appInfo` is still editable — once a version is on sale its `appInfo` is frozen and a
new one is opened alongside it for the next.
"""
app = app_id()

rights = read_meta("content_rights")
if rights:
call("PATCH", f"/v1/apps/{app}", {
"data": {"type": "apps", "id": app, "attributes": {"contentRightsDeclaration": rights}}
})
print(f" content rights: {rights}")

category = read_meta("primary_category")
if category:
for info in call("GET", f"/v1/apps/{app}/appInfos")["data"]:
state = info["attributes"].get("appStoreState") or info["attributes"].get("state")
if state not in ("PREPARE_FOR_SUBMISSION", "DEVELOPER_REJECTED", "REJECTED", "METADATA_REJECTED"):
continue
call("PATCH", f"/v1/appInfos/{info['id']}", {
"data": {
"type": "appInfos",
"id": info["id"],
"relationships": {
"primaryCategory": {"data": {"type": "appCategories", "id": category}}
},
}
})
print(f" primary category: {category}")


# Territories the app is deliberately not offered in. China mainland requires an ICP
# filing number before an app can be listed there, which this app does not have.
EXCLUDED_TERRITORIES = {"CHN"}


def push_pricing() -> None:
"""Free, in every territory except the excluded ones, and in new territories as Apple adds them.

Both are one-time set-ups on a new app — neither exists until something creates it,
and App Store Connect will not accept a submission without them — so this creates
whichever is missing and leaves an existing one alone rather than guessing at an edit.
"""
app = app_id()

def exists(path: str) -> bool:
try:
return bool(call("GET", path, tolerate=True).get("data"))
except ASCError as error:
if error.status == 404:
return False
raise

if exists(f"/v1/apps/{app}/appPriceSchedule"):
print(" price: already set, left alone")
else:
free = [
point
for point in call(
"GET",
f"/v1/apps/{app}/appPricePoints?filter[territory]=USA&limit=5"
"&fields[appPricePoints]=customerPrice",
)["data"]
if float(point["attributes"]["customerPrice"]) == 0
]
if not free:
sys.exit("no free price point found for the USA")
call("POST", "/v1/appPriceSchedules", {
"data": {
"type": "appPriceSchedules",
"relationships": {
"app": {"data": {"type": "apps", "id": app}},
"baseTerritory": {"data": {"type": "territories", "id": "USA"}},
"manualPrices": {"data": [{"type": "appPrices", "id": "${free}"}]},
},
},
"included": [{
"type": "appPrices",
"id": "${free}",
"attributes": {"startDate": None},
"relationships": {
"appPricePoint": {"data": {"type": "appPricePoints", "id": free[0]["id"]}}
},
}],
})
print(" price: free")

if exists(f"/v1/apps/{app}/appAvailabilityV2"):
print(" availability: already set, left alone")
else:
territories = [
t["id"] for t in call("GET", "/v1/territories?limit=200")["data"]
if t["id"] not in EXCLUDED_TERRITORIES
]
call("POST", "/v2/appAvailabilities", {
"data": {
"type": "appAvailabilities",
"attributes": {"availableInNewTerritories": True},
"relationships": {
"app": {"data": {"type": "apps", "id": app}},
"territoryAvailabilities": {
"data": [{"type": "territoryAvailabilities", "id": f"${{{t}}}"} for t in territories]
},
},
},
"included": [
{
"type": "territoryAvailabilities",
"id": f"${{{t}}}",
"attributes": {"available": True},
"relationships": {"territory": {"data": {"type": "territories", "id": t}}},
}
for t in territories
],
})
print(f" availability: {len(territories)} territories, not {', '.join(sorted(EXCLUDED_TERRITORIES))}")


def reviewer_notes() -> str | None:
"""The reviewer-facing block out of `review-notes.md`.

Expand Down Expand Up @@ -841,6 +970,10 @@ def main() -> None:
push_review()
elif command == "agerating":
push_age_rating()
elif command == "info":
push_info()
elif command == "pricing":
push_pricing()
elif command == "version":
if len(sys.argv) < 3:
sys.exit("usage: asc.py version <version-string>")
Expand All @@ -851,6 +984,7 @@ def main() -> None:
submit_for_review()
elif command == "all":
push_text()
push_info()
push_screenshots()
push_review()
push_age_rating()
Expand Down
2 changes: 1 addition & 1 deletion Sources/Cleared/GitHub/GitHubClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ actor GitHubClient {
config.timeoutIntervalForRequest = 20
config.waitsForConnectivity = false
config.httpAdditionalHeaders = [
"User-Agent": "\(AppEnvironment.name)/\(AppEnvironment.version) (+https://github.com/hollandcloud/cleared)",
"User-Agent": "\(AppEnvironment.name)/\(AppEnvironment.version) (+https://github.com/hollandcloud/gitcleared)",
]
self.session = URLSession(configuration: config)
}
Expand Down
1 change: 1 addition & 0 deletions Store/metadata/content_rights.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
USES_THIRD_PARTY_CONTENT
2 changes: 1 addition & 1 deletion Store/metadata/en-US/keywords.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
github,deploy,deployment,approve,actions,pull request,merge,ci,cd,devops,workflow,menu bar,release
git,github,cicd,devops,deploy,deployment,approve,actions,pull request,merge,workflow,menu bar
2 changes: 1 addition & 1 deletion Store/metadata/en-US/marketing_url.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
https://github.com/hollandcloud/cleared
https://github.com/hollandcloud/gitcleared
2 changes: 1 addition & 1 deletion Store/metadata/en-US/name.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
GitCleared
Git Cleared
2 changes: 1 addition & 1 deletion Store/metadata/en-US/privacy_policy_url.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
https://github.com/hollandcloud/cleared/blob/main/docs/privacy.md
https://github.com/hollandcloud/gitcleared/blob/main/docs/privacy.md
2 changes: 1 addition & 1 deletion Store/metadata/en-US/support_url.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
https://github.com/hollandcloud/cleared/blob/main/docs/support.md
https://github.com/hollandcloud/gitcleared/blob/main/docs/support.md
1 change: 1 addition & 0 deletions Store/metadata/primary_category.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DEVELOPER_TOOLS
Binary file modified Store/screenshots/mac/01-queue.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Store/screenshots/mac/02-all-clear.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Store/screenshots/mac/03-start-a-workflow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Store/screenshots/mac/04-settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Store/screenshots/mac/05-connect.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Store/screenshots/raw/all-clear.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Store/screenshots/raw/connect.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Store/screenshots/raw/queue.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Store/screenshots/raw/settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Store/screenshots/raw/start-a-workflow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/privacy.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,6 @@ a new date, and the change will be visible in the repository's history.
## Contact

Questions about this policy: open an issue at
https://github.com/hollandcloud/cleared/issues
https://github.com/hollandcloud/gitcleared/issues

GitCleared is an independent project and is not affiliated with GitHub.
2 changes: 1 addition & 1 deletion docs/support.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ listing.

## Getting help or reporting a bug

Open an issue: **https://github.com/hollandcloud/cleared/issues**
Open an issue: **https://github.com/hollandcloud/gitcleared/issues**

It helps to include:

Expand Down
Loading