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
14 changes: 2 additions & 12 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,7 @@ jobs:
if: startsWith(github.ref, 'refs/tags/v')
# Holds APPCAST_DEPLOY_KEY, released only to v* tags.
environment: release
# Ten deltas at about a minute of CPU each, built two at a time.
timeout-minutes: 30
timeout-minutes: 10
permissions:
contents: write

Expand Down Expand Up @@ -369,13 +368,6 @@ jobs:
fi
echo "::warning::This release is marked critical and will interrupt every user"

# A step of its own, so the token that reads releases never shares an environment with the
# signing key.
- name: Fetch earlier update archives for deltas
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: scripts/ci/fetch-delta-bases.sh "${GITHUB_REF#refs/tags/}" 5 delta-bases

- name: Sign update archives with Sparkle
env:
SPARKLE_PRIVATE_KEY: ${{ secrets.SPARKLE_PRIVATE_KEY }}
Expand Down Expand Up @@ -408,10 +400,8 @@ jobs:
PRERELEASE: ${{ contains(github.ref, '-beta') || contains(github.ref, '-alpha') || contains(github.ref, '-rc') }}
run: |
TAG="${GITHUB_REF#refs/tags/}"
# A first release has nothing to build deltas from.
shopt -s nullglob
scripts/ci/draft-release.sh --prerelease "$PRERELEASE" "$TAG" "$TAG" release_notes.md \
artifacts/*.dmg artifacts/*.tar.xz artifacts/*.delta
artifacts/*.dmg artifacts/*.tar.xz

- name: Publish the release
if: steps.draft.outputs.id != ''
Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Plugins signed by other developers stop loading, and HTML and XML export are rem
- tablepro command ships inside the app, linked from a Terminal line in Settings > General without an admin prompt. (#3372)
- MCP server runs only while Enable MCP Server is on in Settings > MCP, including for clients and pairing. (#3368)
- Edit > Data shown only in data file windows. (#3364)
- Smaller updates: about 6 MB from any of the last five releases and 21 MB from older ones, down from 34 MB. (#3363)
- Smaller updates: 20 MB on Apple silicon and 23 MB on Intel, down from 32 MB and 35 MB. (#3363)
- PostgreSQL on iPhone and iPad commits several statements one at a time, keeping the ones before a failure. (#3399, #3404)
- MySQL dumps write TIMESTAMP values in UTC and turn off foreign key checks while they load, as mysqldump does. (#3427)
- AI chat code blocks show all their code in the editor font and colors, without line numbers. (#3432)
Expand Down
9 changes: 4 additions & 5 deletions RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,10 @@ ref, so a dispatch from a branch only builds. The tag runs no test suite.
the tag disagrees with `MARKETING_VERSION` (`tag v... does not match MARKETING_VERSION ...`).
- It also fails when `CURRENT_PROJECT_VERSION` is not above the newest published release's. Sparkle
compares that number as `<sparkle:version>`, so a flat one ships a release no install is offered.
- It signs both update archives with the Sparkle key, builds deltas from the previous five
releases' archives, and takes the notes from `CHANGELOG.md`.
- It checks that the appcast deploy key works before publishing anything. Then it puts both DMGs,
both update archives and the deltas on a draft release, publishes the draft in one step, and only
then commits `appcast.xml`, whose download URLs 404 until the release is public.
- It signs both update archives with the Sparkle key and takes the notes from `CHANGELOG.md`.
- It checks that the appcast deploy key works before publishing anything. Then it puts both DMGs
and both update archives on a draft release, publishes the draft in one step, and only then
commits `appcast.xml`, whose download URLs 404 until the release is public.
- The appcast is merged with the tag's own copy of `scripts/ci/merge-appcast.py` and pushed with
`APPCAST_DEPLOY_KEY`, up to 3 attempts, each re-merging onto the current `origin/main`.
- `generate_appcast` sees only the new release. The merge script splices its items in and moves
Expand Down
14 changes: 0 additions & 14 deletions appcast.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,6 @@ Plugins signed by other developers stop loading, and HTML and XML export are rem
[View full changelog](https://docs.tablepro.app/changelog)
]]></description>
<enclosure url="https://github.com/TableProApp/TablePro/releases/download/v0.81.0/TablePro-0.81.0-arm64.tar.xz" length="21031520" type="application/octet-stream" sparkle:edSignature="oX/vZ7mefH5HbArzgCwsLfRFYAfkzYsOVo2zSUlEOWry5dxYY0CTkp1+U+AKE82PHXii/SfRLDgxVu/MmwixBA=="/>
<sparkle:deltas>
<enclosure url="https://github.com/TableProApp/TablePro/releases/download/v0.81.0/TablePro-0.81.0-from-139-arm64.delta" sparkle:deltaFrom="139" length="15076138" type="application/octet-stream" sparkle:deltaFromSparkleExecutableSize="976432" sparkle:deltaFromSparkleLocales="de,he,ar,el,ja,fa,uk" sparkle:edSignature="eWfZAaiGAXxbKzLDFgu2g1U2BQcI976mv9ycEVWZCnEwZmnQgZJBldC7DJNLxxkVoDAvelUr0maBU2z2as29Aw=="/>
<enclosure url="https://github.com/TableProApp/TablePro/releases/download/v0.81.0/TablePro-0.81.0-from-138-arm64.delta" sparkle:deltaFrom="138" length="15723602" type="application/octet-stream" sparkle:deltaFromSparkleExecutableSize="976432" sparkle:deltaFromSparkleLocales="de,he,ar,el,ja,fa,uk" sparkle:edSignature="lZFeE11V/MIrMx1vniOvwjYgFU2zhlsGqUykiYZ1NQvJWQveLebcM7fFnwaTcEASWNPSWMQ5sBP8vvSSAj2PDQ=="/>
<enclosure url="https://github.com/TableProApp/TablePro/releases/download/v0.81.0/TablePro-0.81.0-from-137-arm64.delta" sparkle:deltaFrom="137" length="15785870" type="application/octet-stream" sparkle:deltaFromSparkleExecutableSize="976432" sparkle:deltaFromSparkleLocales="de,he,ar,el,ja,fa,uk" sparkle:edSignature="+ODaOsw70dDFQ/Y9jhpVfy073GewU6uZrtTKZ2uw1PoooILsE3UEMJ8Kl/HiQC9N58TT0GRdDLFzlLF9qEAUCg=="/>
<enclosure url="https://github.com/TableProApp/TablePro/releases/download/v0.81.0/TablePro-0.81.0-from-136-arm64.delta" sparkle:deltaFrom="136" length="16054146" type="application/octet-stream" sparkle:deltaFromSparkleExecutableSize="976432" sparkle:deltaFromSparkleLocales="de,he,ar,el,ja,fa,uk" sparkle:edSignature="MIB14omVWwe2WmHIsC8+brXHbsm0wsDvBB56kOyOMYFwrpnMPuFmv5a2WCuILpoR88TWFyv8tSOgNPqi/jx5CQ=="/>
<enclosure url="https://github.com/TableProApp/TablePro/releases/download/v0.81.0/TablePro-0.81.0-from-135-arm64.delta" sparkle:deltaFrom="135" length="16134514" type="application/octet-stream" sparkle:deltaFromSparkleExecutableSize="976432" sparkle:deltaFromSparkleLocales="de,he,ar,el,ja,fa,uk" sparkle:edSignature="H0TJn8fyhIOHW8IxHow8BV8D5vCFwuqHI6BQoK4NYxUnZCFi761BfMBjkrZgR2yxQyeua4aaMW100TM9qvWxBQ=="/>
</sparkle:deltas>
</item>
<item>
<title>0.81.0</title>
Expand All @@ -53,13 +46,6 @@ Plugins signed by other developers stop loading, and HTML and XML export are rem
[View full changelog](https://docs.tablepro.app/changelog)
]]></description>
<enclosure url="https://github.com/TableProApp/TablePro/releases/download/v0.81.0/TablePro-0.81.0-x86_64.tar.xz" length="24299872" type="application/octet-stream" sparkle:edSignature="+AtQqogGVMWwCKR9DDLpKmUC4JMcp8Un6FiBuIefOMUtfNgNOlkNAzmyorLgQOhW6VXAF7QP/FL3FHNncfhRDg=="/>
<sparkle:deltas>
<enclosure url="https://github.com/TableProApp/TablePro/releases/download/v0.81.0/TablePro-0.81.0-from-139-x86_64.delta" sparkle:deltaFrom="139" length="17555770" type="application/octet-stream" sparkle:deltaFromSparkleExecutableSize="976432" sparkle:deltaFromSparkleLocales="de,he,ar,el,ja,fa,uk" sparkle:edSignature="FaGWHyNDDe2aGHkem30Fhs0XFYxqeuY+hTjXUGsfDmzIZM6zYAU023SVp8LzNDZ+YLpJlzi7t8f+oE7erhJ8Bg=="/>
<enclosure url="https://github.com/TableProApp/TablePro/releases/download/v0.81.0/TablePro-0.81.0-from-138-x86_64.delta" sparkle:deltaFrom="138" length="18273326" type="application/octet-stream" sparkle:deltaFromSparkleExecutableSize="976432" sparkle:deltaFromSparkleLocales="de,he,ar,el,ja,fa,uk" sparkle:edSignature="SnajrARCQIEAsOcFKrKWv/c7l8gyPzOuEc/DzR1cepQRMtijjUklr3PPPADJEa8eRdtL3tiiyyOCD76tiI3aAg=="/>
<enclosure url="https://github.com/TableProApp/TablePro/releases/download/v0.81.0/TablePro-0.81.0-from-137-x86_64.delta" sparkle:deltaFrom="137" length="18346618" type="application/octet-stream" sparkle:deltaFromSparkleExecutableSize="976432" sparkle:deltaFromSparkleLocales="de,he,ar,el,ja,fa,uk" sparkle:edSignature="hj8lOu9n4voEzW3bLcBAsuY1r086pTwrDAEPZy59ajJBEL5qZ+fK+NlHbhyaj3tMy2ak+Iv4Ox6zKFptz87qBA=="/>
<enclosure url="https://github.com/TableProApp/TablePro/releases/download/v0.81.0/TablePro-0.81.0-from-136-x86_64.delta" sparkle:deltaFrom="136" length="18627454" type="application/octet-stream" sparkle:deltaFromSparkleExecutableSize="976432" sparkle:deltaFromSparkleLocales="de,he,ar,el,ja,fa,uk" sparkle:edSignature="VbqTIq8pkDQ4PLsbK+F0DfLblcLeS9uMvmDmLzzoaSTfnYOJjGdogvy+7STmF23z/JyKR5fOLORGZp83AAPVDA=="/>
<enclosure url="https://github.com/TableProApp/TablePro/releases/download/v0.81.0/TablePro-0.81.0-from-135-x86_64.delta" sparkle:deltaFrom="135" length="18725834" type="application/octet-stream" sparkle:deltaFromSparkleExecutableSize="976432" sparkle:deltaFromSparkleLocales="de,he,ar,el,ja,fa,uk" sparkle:edSignature="yp+s9Je7B0CPC6f2AV49MT2ePuUO+s37jS3+JGzhfHV5ADytleQqt1X4muW3Mgl1GO5mFixltOLCzc/+m6NyAA=="/>
</sparkle:deltas>
</item>
<item>
<title>0.80.0</title>
Expand Down
7 changes: 1 addition & 6 deletions scripts/ci/appcast_feed.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
SHORT_VERSION = f"{{{SPARKLE_NS}}}shortVersionString"
BUNDLE_VERSION = f"{{{SPARKLE_NS}}}version"
HARDWARE = f"{{{SPARKLE_NS}}}hardwareRequirements"
DELTAS = f"{{{SPARKLE_NS}}}deltas"
ED_SIGNATURE = f"{{{SPARKLE_NS}}}edSignature"


Expand Down Expand Up @@ -66,11 +65,7 @@ def item_bundle_version(item):


def item_enclosures(item):
enclosures = list(item.findall("enclosure"))
deltas = item.find(DELTAS)
if deltas is not None:
enclosures.extend(deltas.findall("enclosure"))
return enclosures
return list(item.findall("enclosure"))


SKIPPABLE = (("<![CDATA[", "]]>", "CDATA section"), ("<!--", "-->", "comment"))
Expand Down
49 changes: 0 additions & 49 deletions scripts/ci/fetch-delta-bases.sh

This file was deleted.

11 changes: 2 additions & 9 deletions scripts/ci/merge-appcast.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@

`generate_appcast` keeps only what it is handed, so the release used to hand it the whole
published feed as a seed. That is safe only while the staging directory holds nothing but the new
archive, and it stops being true as soon as anything else is staged, which generating deltas
requires. Verified in the pinned Sparkle 2.9.5 source: `FeedXML.swift:333-339` matches an existing
item by version, and two writes then run outside the resulting `if createNewItem` guard. Line 603
archive, and it stops being true as soon as anything else is staged. Verified in the pinned
Sparkle 2.9.5 source: `FeedXML.swift:333-339` matches an existing item by version, and two writes then run outside the resulting `if createNewItem` guard. Line 603
assigns the enclosure's attributes unconditionally, so a seeded item matched by a staged archive
has its download URL rewritten into the current release's directory, which is a permanent 404.
Lines 523-525 remove that item's `<description>` when the staged archive has no sibling notes
Expand Down Expand Up @@ -89,7 +88,6 @@ def check_new_items(arm64_item, x86_64_item, version, download_prefix):
f"arm64 {arm64_bundle!r}, x86_64 {x86_64_bundle!r}"
)

advertised = {}
for label, item in (("arm64", arm64_item), ("x86_64", x86_64_item)):
enclosures = item_enclosures(item)
if not enclosures:
Expand All @@ -100,11 +98,6 @@ def check_new_items(arm64_item, x86_64_item, version, download_prefix):
raise FeedError(
f"the {label} item advertises {url!r}, which is not under {download_prefix!r}"
)
# One release directory holds both architectures, so a shared name is one asset
# serving two different files.
if url in advertised:
raise FeedError(f"{url!r} is advertised twice, by the {advertised[url]} and {label} items")
advertised[url] = label
# generate_appcast signs an archive only when the app's own Info.plist declares
# SUPublicEDKey (Appcast.swift:199 in 2.9.5). Drop that key and it writes an unsigned
# enclosure, reports "Wrote 1 new update" and exits 0, and every installed updater
Expand Down
109 changes: 0 additions & 109 deletions scripts/ci/name-deltas.py

This file was deleted.

Loading
Loading