From e979276c9940b45ef114d21175cbbd3c37eb5d20 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Mon, 17 Aug 2026 15:07:23 +0200 Subject: [PATCH] Import the other two scripts rather than load them by hand The store copy script reached the listing and the changelog by opening those files and running them, because neither was named something Python can say. Both are renamed. The changelog reader moves out of the workflow folder while we are here, and the version reader with it, so every script sits in one place and a script that needs another one is simply next to it. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01E6tn8P25cBDmrA67zrhfwN --- .github/workflows/release.yml | 12 ++++++------ README.md | 6 +++--- fastlane/Fastfile | 4 ++-- fastlane/metadata/README.md | 8 ++++---- .../changelog_section.py | 0 .../scripts => scripts}/resolve-version.py | 0 scripts/store-copy.py | 18 ++++-------------- scripts/{store-listing.py => store_listing.py} | 6 +++--- scripts/store_screenshots.py | 3 --- 9 files changed, 22 insertions(+), 35 deletions(-) rename .github/scripts/changelog-section.py => scripts/changelog_section.py (100%) rename {.github/scripts => scripts}/resolve-version.py (100%) rename scripts/{store-listing.py => store_listing.py} (98%) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 98770f4..407ad68 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -60,14 +60,14 @@ jobs: # would be a shell injection env: given: ${{ inputs.version }} - run: .github/scripts/resolve-version.py --input "$given" --dry-run "$dry_run" + run: scripts/resolve-version.py --input "$given" --dry-run "$dry_run" # this section becomes the release body, so a dry run checks it too - name: check the changelog names this version if: ${{ steps.version.outputs.version != '' }} env: version: ${{ steps.version.outputs.version }} - run: .github/scripts/changelog-section.py --version "$version" + run: scripts/changelog_section.py --version "$version" # what the listing job uploads, so a missing translation fails here rather # than once both apps are up @@ -75,7 +75,7 @@ jobs: if: ${{ steps.version.outputs.version != '' }} env: version: ${{ steps.version.outputs.version }} - run: scripts/store-listing.py --version "$version" + run: scripts/store_listing.py --version "$version" - uses: ruby/setup-ruby@v1 with: @@ -298,7 +298,7 @@ jobs: id: version env: given: ${{ inputs.version }} - run: .github/scripts/resolve-version.py --input "$given" --dry-run "$dry_run" + run: scripts/resolve-version.py --input "$given" --dry-run "$dry_run" # where the lane looks for them, and the same set both apps are given - name: fetch the screenshots @@ -330,7 +330,7 @@ jobs: id: version env: given: ${{ inputs.version }} - run: .github/scripts/resolve-version.py --input "$given" --dry-run "$dry_run" + run: scripts/resolve-version.py --input "$given" --dry-run "$dry_run" - name: fetch the ipas uses: actions/download-artifact@v8 @@ -375,7 +375,7 @@ jobs: version: ${{ steps.version.outputs.version }} run: | set -euo pipefail - .github/scripts/changelog-section.py --version "$version" > "${RUNNER_TEMP}/notes.md" + scripts/changelog_section.py --version "$version" > "${RUNNER_TEMP}/notes.md" # the version input is bare, the tag it publishes is prefixed tag="v$version" diff --git a/README.md b/README.md index fabb71f..2aa2a9a 100644 --- a/README.md +++ b/README.md @@ -156,7 +156,7 @@ heading. The copy lives in `fastlane/metadata//changelogs/1.41.txt`, one file per version per locale, because App Store Connect keeps only the notes of the -submission in flight. `scripts/store-listing.py` checks it - the release run +submission in flight. `scripts/store_listing.py` checks it - the release run refuses a version any locale is missing, before it builds anything - and stages it into the shape `deliver` reads. @@ -217,8 +217,8 @@ The build number is resolved once and given to both apps, so one `(version, buil pair names one commit in both listings. App Store Connect only requires it to increase, not to be contiguous, so whichever app was behind skips ahead. -`.github/scripts/resolve-version.py` decides which version a run builds and -refuses runs that cannot name one; `changelog-section.py` refuses a version with +`scripts/resolve-version.py` decides which version a run builds and +refuses runs that cannot name one; `scripts/changelog_section.py` refuses a version with no `CHANGELOG.md` section, before anything is built, since that section becomes the release body. Run either by hand to see what a dispatch would do. diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 6b2ea02..3728204 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -20,7 +20,7 @@ IPA_DIR = File.expand_path("../build").freeze # Absolute for the same reason. They resolve the repository from their own path, # so they do not care which of the two they are called from. -STORE_LISTING = File.expand_path("../scripts/store-listing.py").freeze +STORE_LISTING = File.expand_path("../scripts/store_listing.py").freeze STORE_SCREENSHOTS = File.expand_path("../scripts/store_screenshots.py").freeze FRAME_SCREENSHOTS = File.expand_path("../scripts/frame-screenshots.py").freeze MAKE_DOCUMENTS = File.expand_path("../scripts/make-screenshot-documents.py").freeze @@ -368,7 +368,7 @@ platform :ios do # # deliver uploads every metadata file it finds under metadata_path, so it is # given a staged directory rather than fastlane/metadata itself, and - # store-listing.py names what goes into it. What is staged is what this + # store_listing.py names what goes into it. What is staged is what this # repository says the store should say; anything else is left as App Store # Connect has it. # diff --git a/fastlane/metadata/README.md b/fastlane/metadata/README.md index bf4680f..1ca3a40 100644 --- a/fastlane/metadata/README.md +++ b/fastlane/metadata/README.md @@ -9,7 +9,7 @@ going out. What the store says is what is committed here. Two things are left out of the upload on purpose. `review_information` is the account's contact details and the note to the reviewer, and the category files say where the app sits in the store - neither is release copy. -`scripts/store-listing.py` names what is staged, so adding a file to that list is +`scripts/store_listing.py` names what is staged, so adding a file to that list is a decision rather than an accident. ## The two apps @@ -34,7 +34,7 @@ line: Lite shows ads and Pro does not. Rather than keep two descriptions per locale and let them drift, the shared one holds `${ads}` and each app fills it in from its own `ads.txt` - Lite has one per locale, Pro has none, and a fill-in nobody answers leaves nothing behind, the space in front of it -included. `FILL_INS` in `scripts/store-listing.py` lists the names one may +included. `FILL_INS` in `scripts/store_listing.py` lists the names one may have, so a misspelt `${adds}` is an error rather than a sentence that quietly vanishes from the store. @@ -54,7 +54,7 @@ files are the history the store does not keep. The limit is 4000 characters per locale. `deliver` does not read this layout. It reads one `release_notes.txt` per -locale, so `scripts/store-listing.py` stages the version's file under that name +locale, so `scripts/store_listing.py` stages the version's file under that name into a throwaway directory at upload time, with the rest of the listing beside it. @@ -83,7 +83,7 @@ anything. ## Name, subtitle, keywords 30 characters for the name, 30 for the subtitle, 100 for the keywords, counting -the commas. `scripts/store-listing.py` checks all three against what it stages +the commas. `scripts/store_listing.py` checks all three against what it stages rather than against what is written here, since an app's own name is what finally has to fit. diff --git a/.github/scripts/changelog-section.py b/scripts/changelog_section.py similarity index 100% rename from .github/scripts/changelog-section.py rename to scripts/changelog_section.py diff --git a/.github/scripts/resolve-version.py b/scripts/resolve-version.py similarity index 100% rename from .github/scripts/resolve-version.py rename to scripts/resolve-version.py diff --git a/scripts/store-copy.py b/scripts/store-copy.py index a6a625c..ef74a66 100755 --- a/scripts/store-copy.py +++ b/scripts/store-copy.py @@ -21,29 +21,19 @@ # Unreleased while the heading is still open. A file that is already there is # left alone and translated, since that is the copy that was reviewed. # -# Nothing here uploads: `scripts/store-listing.py` checks and stages what this +# Nothing here uploads: `scripts/store_listing.py` checks and stages what this # writes, and the release run uploads it. import argparse import concurrent.futures -import importlib.util import subprocess import sys from pathlib import Path -ROOT = Path(__file__).resolve().parent.parent - - -def load(path, name): - """Import a sibling script, whose file name is not an identifier.""" - spec = importlib.util.spec_from_file_location(name, path) - module = importlib.util.module_from_spec(spec) - spec.loader.exec_module(module) - return module +import changelog_section as changelog +import store_listing as listing - -listing = load(ROOT / "scripts" / "store-listing.py", "store_listing") -changelog = load(ROOT / ".github" / "scripts" / "changelog-section.py", "changelog_section") +ROOT = Path(__file__).resolve().parent.parent SOURCE = "en-US" diff --git a/scripts/store-listing.py b/scripts/store_listing.py similarity index 98% rename from scripts/store-listing.py rename to scripts/store_listing.py index 8b65499..7f2d6bf 100755 --- a/scripts/store-listing.py +++ b/scripts/store_listing.py @@ -11,9 +11,9 @@ # staged directory rather than at fastlane/metadata itself, and what is copied # in is named here rather than being whatever happens to be lying around. # -# scripts/store-listing.py --version 1.41 check the notes -# scripts/store-listing.py --version 1.41 --stage DIR notes alone -# scripts/store-listing.py --version 1.41 --stage DIR --app pro the whole listing +# scripts/store_listing.py --version 1.41 check the notes +# scripts/store_listing.py --version 1.41 --stage DIR notes alone +# scripts/store_listing.py --version 1.41 --stage DIR --app pro the whole listing # # The two apps share one listing and differ in a few places, so what is staged # is read in three passes - `fastlane/metadata//`, then the app's own diff --git a/scripts/store_screenshots.py b/scripts/store_screenshots.py index e454636..d0c8605 100755 --- a/scripts/store_screenshots.py +++ b/scripts/store_screenshots.py @@ -12,9 +12,6 @@ # scripts/store_screenshots.py check what was captured # scripts/store_screenshots.py --stage DIR check it and stage it # -# Named with an underscore, unlike its neighbours, because frame-screenshots.py -# imports it and a hyphen is not an identifier. -# # The store has eleven locales and the app is translated into nine of them. # The other two get the English pictures, which is what their storefront would # show anyway: the app has no UI in Hindi or Swedish either.