diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 0c14d34..2c0cb6d 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -34,12 +34,13 @@ jobs:
uses: beeware/.github/.github/workflows/app-build-verify.yml@main
with:
python-version: ${{ matrix.python-version }}
- runner-os: macos-15
+ runner-os: macos-26
framework: ${{ matrix.framework }}
target-platform: iOS
target-format: Xcode
+ ios-simulator: "iPhone 17e::iOS 26.5"
strategy:
fail-fast: false
matrix:
- python-version: [ "3.10", "3.11", "3.12", "3.13", "3.14" ]
+ python-version: ["3.11", "3.12", "3.13", "3.14", "3.15" ]
framework: [ "toga" ]
diff --git a/.gitignore b/.gitignore
index 21d5e56..5b83825 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
.python-version
.vscode
.idea
+.rumdl_cache
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 7c24bbd..d5a5f83 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -8,6 +8,11 @@ repos:
- id: check-case-conflict
- id: end-of-file-fixer
- id: trailing-whitespace
+ - repo: https://github.com/rvben/rumdl-pre-commit
+ rev: v0.2.60
+ hooks:
+ - id: rumdl
+ - id: rumdl-fmt
- repo: https://github.com/zizmorcore/zizmor-pre-commit
rev: v1.29.0
hooks:
diff --git a/README.md b/README.md
index a122b83..4dfbe24 100644
--- a/README.md
+++ b/README.md
@@ -8,38 +8,44 @@ The easiest way to use this project is to not use it at all - at least, not dire
However, if you *do* want to use this template directly...
-1. Install [cookiecutter](https://github.com/cookiecutter/cookiecutter). This is a tool used to bootstrap complex project templates:
+1. Install [cookiecutter](https://github.com/cookiecutter/cookiecutter). This is a tool used to bootstrap complex project templates:
- $ pip install cookiecutter
+ ```text
+ $ pip install cookiecutter
+ ```
-2. Run `cookiecutter` on the template:
+2. Run `cookiecutter` on the template:
- $ cookiecutter https://github.com/beeware/briefcase-iOS-Xcode-template
+ ```text
+ $ cookiecutter https://github.com/beeware/briefcase-iOS-Xcode-template
+ ```
- This will ask you for a number of details of your application, including the name of your application (which should be a valid PyPI identifier), and the Formal Name of your application (the full name you use to describe your app). The remainder of these instructions will assume a name of `my-project`, and a formal name of `My Project`.
+ This will ask you for a number of details of your application, including the name of your application (which should be a valid PyPI identifier), and the formal name of your application (the full name you use to describe your app). The remainder of these instructions will assume a name of `my-project`, and a formal name of `My Project`.
-3. [Obtain a Python Apple support package for iOS](https://github.com/beeware/Python-Apple-support), and extract it into the `My Project` directory generated by the template. This will give you a `Xcode/Support` directory containing a self contained Python install.
+3. [Obtain a Python Apple support package for iOS](https://github.com/beeware/Python-Apple-support), and extract it into the `My Project` directory generated by the template. This will give you a `Xcode/Support` directory containing a self contained Python install.
-4. Add your code to the template, into the `Xcode/my-project/app`. directory. At the very minimum, you need to have an `app//__main__.py` file that defines a `PythonAppDelegate` class.
+4. Add your code to the template, into the `Xcode/my-project/app`. directory. At the very minimum, you need to have an `app//__main__.py` file that defines a `PythonAppDelegate` class.
If your code has any dependencies, they should be installed into the `Xcode/my-project/app_packages` directory.
If you've done this correctly, a project with a formal name of `My Project`, with an app name of `my-project` should have a directory structure that looks something like:
- Xcode/
- my-project/
- app/
- my_project/
- __init__.py
- app.py (declares PythonAppDelegate)
- app_packages/
- ...
+```text
+Xcode/
+ my-project/
+ app/
+ my_project/
+ __init__.py
+ app.py (declares PythonAppDelegate)
+ app_packages/
...
- My Project.xcodeproj/
- ...
- Support/
- ...
- briefcase.toml
+ ...
+ My Project.xcodeproj/
+ ...
+ Support/
+ ...
+ briefcase.toml
+```
You're now ready to open the XCode project file, build and run your project!
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..13b092d
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,29 @@
+[tool.rumdl]
+flavor = "mkdocs"
+include = ["**/*.md"]
+exclude = ["comment.md", "CODE_OF_CONDUCT.md"]
+respect-gitignore = true
+force-exclude = true
+
+# Disable rules:
+# MD014: Forces commands in codeblocks to show output
+# MD042: Empty link - buggy, still flagging on valid MkDocs formatting
+# MD052: Reference link not found - buggy, flagging on valis MkDocs links
+disable = ["MD014", "MD042", "MD052"]
+
+[tool.rumdl.MD007]
+indent = 4
+
+[tool.rumdl.MD013] # Line length
+line_length = 999999 # Force reflow to paragraph content to remove linebreaks
+reflow = true
+reflow_mode = "normalize"
+
+[tool.rumdl.MD026] # Remove punctuation at the end of headings
+punctuation = ",;:"
+
+[tool.rumdl.MD033] # No inline HTML
+allowed_elements = ["nospell",] # pyspelling inline disable tag
+
+[tool.rumdl.MD046]
+style = "fenced"
diff --git a/{{ cookiecutter.format }}/briefcase.toml b/{{ cookiecutter.format }}/briefcase.toml
index 3c5b64d..bcbcdca 100644
--- a/{{ cookiecutter.format }}/briefcase.toml
+++ b/{{ cookiecutter.format }}/briefcase.toml
@@ -9,11 +9,11 @@ app_packages_path = "{{ cookiecutter.class_name }}/app_packages"
info_plist_path = "{{ cookiecutter.class_name }}/{{ cookiecutter.class_name }}-Info.plist"
support_path = "Support"
{{ {
- "3.10": "support_revision = 14",
- "3.11": "support_revision = 9",
- "3.12": "support_revision = 9",
- "3.13": "support_revision = 14",
- "3.14": "support_revision = 10",
+ "3.11": "support_revision = 10",
+ "3.12": "support_revision = 10",
+ "3.13": "support_revision = 15",
+ "3.14": "support_revision = 11",
+ "3.15": "support_revision = 0",
}.get(cookiecutter.python_version|py_tag, "") }}
icon.20 = "{{ cookiecutter.class_name }}/Images.xcassets/AppIcon.appiconset/icon-20.png"