From c6eeccc25cbe1cd9e78c95f40a6413d2cd1a21a6 Mon Sep 17 00:00:00 2001 From: Kevin van Zonneveld Date: Wed, 7 Oct 2026 14:17:45 +0200 Subject: [PATCH 1/4] Document the TransloaditKit release process --- CONTRIBUTING.md | 118 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..af7365b --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,118 @@ +# Contributing + +Build and run the tests on macOS with Xcode installed: + +```sh +swift build +swift test +``` + +## Releasing + +Release preparation and publication are separate steps. Prepare a PR that: + +- Updates `s.version` in `Transloadit.podspec`. +- Updates `TransloaditAPI.clientHeader` in `Sources/TransloaditKit/TransloaditAPI.swift` to the same version. +- Moves the release notes from `## Next` into a `## VERSION` section in `CHANGELOG.md`, leaving `## Next` for future changes. + +Merge the preparation PR into `main` and confirm its build and tests pass before publishing. +For 3.6.0, the preparation PR was #47 and the merged commit was +`d6628f3d7fe5b90bc8271f4912d7cadb25360a27`. + +### Tag and GitHub release + +The commands below show 3.6.0. For a new release, replace the version and commit +with those from its merged preparation PR. From the repository checkout: + +```sh +set -e +RELEASE_VERSION=3.6.0 +RELEASE_COMMIT=d6628f3d7fe5b90bc8271f4912d7cadb25360a27 +git fetch origin main --tags +git merge-base --is-ancestor "$RELEASE_COMMIT" origin/main +git tag -a "$RELEASE_VERSION" "$RELEASE_COMMIT" -m "$RELEASE_VERSION" +git push origin "refs/tags/$RELEASE_VERSION" +``` + +Use the matching changelog section, including its heading, as the release body: + +```sh +RELEASE_NOTES="$(mktemp)" +git show "$RELEASE_COMMIT:CHANGELOG.md" | awk -v version="$RELEASE_VERSION" ' + /^## / { + if (release) exit + release = ($0 == "## " version) + } + release { print } +' > "$RELEASE_NOTES" +test -s "$RELEASE_NOTES" +gh release create "$RELEASE_VERSION" --repo transloadit/TransloaditKit \ + --verify-tag --title "$RELEASE_VERSION" --notes-file "$RELEASE_NOTES" +rm "$RELEASE_NOTES" +``` + +Confirm the published release has the expected notes and that the tag points to +the merged preparation commit. + +### CocoaPods publication + +Use a macOS machine with Xcode and CocoaPods installed. A pod owner must run +`pod trunk register` on that machine and confirm the session through the +verification email. Run `pod trunk me` to confirm the session is verified and +lists `Transloadit` before pushing. + +The [3.6.0 release on trunk](https://trunk.cocoapods.org/api/v1/pods/Transloadit/versions/3.6.0) +was published on `studio1` with CocoaPods 1.17.0 and Xcode 27.0. Connect with +`ssh studio1`, then use its clean repository checkout: + +```sh +set -e +cd ~/code/TransloaditKit +pod trunk me +RELEASE_VERSION=3.6.0 +RELEASE_COMMIT=d6628f3d7fe5b90bc8271f4912d7cadb25360a27 +test -z "$(git status --porcelain=v1)" +git fetch origin main --tags +git checkout --detach "$RELEASE_VERSION" +test "$(git rev-parse HEAD)" = "$RELEASE_COMMIT" +``` + +Publish with `pod trunk push Transloadit.podspec` when the Xcode toolchain supports +the podspec's deployment targets. + +For 3.6.0, the plain push failed because Xcode 27 rejected the podspec's iOS 10.0 +and macOS 10.11 deployment targets. It also warned that the referenced `LICENSE` +file is missing and that an existing `identifier` binding is unused. The +successful push used a temporary build configuration with Xcode's supported +deployment targets and allowed those existing warnings: + +```sh +RELEASE_VALIDATION_DIR="$(mktemp -d -t transloaditkit-release)" +cat > "$RELEASE_VALIDATION_DIR/validation.xcconfig" <<'XCCONFIG' +IPHONEOS_DEPLOYMENT_TARGET = 15.0 +MACOSX_DEPLOYMENT_TARGET = 12.0 +XCCONFIG +XCODE_XCCONFIG_FILE="$RELEASE_VALIDATION_DIR/validation.xcconfig" \ + pod trunk push Transloadit.podspec --allow-warnings +rm "$RELEASE_VALIDATION_DIR/validation.xcconfig" +rmdir "$RELEASE_VALIDATION_DIR" +``` + +This override applies only to the validation build. The published podspec still +comes from the release tag; build and import validation remain enabled. +It validates iOS 15.0 and macOS 12.0, rather than the older deployment targets +declared by the podspec. + +The 3.6.0 push returned GitHub commit API timeouts despite completing publication. +Run `pod trunk info Transloadit` and confirm the version is absent before retrying +an interrupted push. + +After a successful push, confirm the version is listed on trunk: + +```sh +pod trunk info Transloadit +git switch main +``` + +A release is complete when its tag, GitHub release, and CocoaPods trunk version +are all published. From dd495398367e4197ba9195aacca84b4efaa970e1 Mon Sep 17 00:00:00 2001 From: Kevin van Zonneveld Date: Wed, 7 Oct 2026 14:25:18 +0200 Subject: [PATCH 2/4] Keep release command errors within subshells --- CONTRIBUTING.md | 89 +++++++++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 43 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index af7365b..5cdb832 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -22,33 +22,33 @@ For 3.6.0, the preparation PR was #47 and the merged commit was ### Tag and GitHub release The commands below show 3.6.0. For a new release, replace the version and commit -with those from its merged preparation PR. From the repository checkout: +with those from its merged preparation PR. From the repository checkout, create +an annotated tag and use the matching changelog section, including its heading, +as the GitHub release body. Continue only after each command block succeeds. ```sh -set -e -RELEASE_VERSION=3.6.0 -RELEASE_COMMIT=d6628f3d7fe5b90bc8271f4912d7cadb25360a27 -git fetch origin main --tags -git merge-base --is-ancestor "$RELEASE_COMMIT" origin/main -git tag -a "$RELEASE_VERSION" "$RELEASE_COMMIT" -m "$RELEASE_VERSION" -git push origin "refs/tags/$RELEASE_VERSION" -``` - -Use the matching changelog section, including its heading, as the release body: - -```sh -RELEASE_NOTES="$(mktemp)" -git show "$RELEASE_COMMIT:CHANGELOG.md" | awk -v version="$RELEASE_VERSION" ' - /^## / { - if (release) exit - release = ($0 == "## " version) - } - release { print } -' > "$RELEASE_NOTES" -test -s "$RELEASE_NOTES" -gh release create "$RELEASE_VERSION" --repo transloadit/TransloaditKit \ - --verify-tag --title "$RELEASE_VERSION" --notes-file "$RELEASE_NOTES" -rm "$RELEASE_NOTES" +( + set -e + RELEASE_VERSION=3.6.0 + RELEASE_COMMIT=d6628f3d7fe5b90bc8271f4912d7cadb25360a27 + git fetch origin main --tags + git merge-base --is-ancestor "$RELEASE_COMMIT" origin/main + git tag -a "$RELEASE_VERSION" "$RELEASE_COMMIT" -m "$RELEASE_VERSION" + git push origin "refs/tags/$RELEASE_VERSION" + + RELEASE_NOTES="$(mktemp)" + trap 'rm -f "$RELEASE_NOTES"' EXIT + git show "$RELEASE_COMMIT:CHANGELOG.md" | awk -v version="$RELEASE_VERSION" ' + /^## / { + if (release) exit + release = ($0 == "## " version) + } + release { print } + ' > "$RELEASE_NOTES" + test -s "$RELEASE_NOTES" + gh release create "$RELEASE_VERSION" --repo transloadit/TransloaditKit \ + --verify-tag --title "$RELEASE_VERSION" --notes-file "$RELEASE_NOTES" +) ``` Confirm the published release has the expected notes and that the tag points to @@ -57,24 +57,25 @@ the merged preparation commit. ### CocoaPods publication Use a macOS machine with Xcode and CocoaPods installed. A pod owner must run -`pod trunk register` on that machine and confirm the session through the -verification email. Run `pod trunk me` to confirm the session is verified and -lists `Transloadit` before pushing. +`pod trunk register` with their pod-owner email address on that machine and +confirm the session through the verification email. Run `pod trunk me` to +confirm the session is verified and lists `Transloadit` before pushing. The [3.6.0 release on trunk](https://trunk.cocoapods.org/api/v1/pods/Transloadit/versions/3.6.0) was published on `studio1` with CocoaPods 1.17.0 and Xcode 27.0. Connect with `ssh studio1`, then use its clean repository checkout: ```sh -set -e -cd ~/code/TransloaditKit -pod trunk me -RELEASE_VERSION=3.6.0 -RELEASE_COMMIT=d6628f3d7fe5b90bc8271f4912d7cadb25360a27 -test -z "$(git status --porcelain=v1)" -git fetch origin main --tags -git checkout --detach "$RELEASE_VERSION" -test "$(git rev-parse HEAD)" = "$RELEASE_COMMIT" +cd ~/code/TransloaditKit && ( + set -e + pod trunk me + RELEASE_VERSION=3.6.0 + RELEASE_COMMIT=d6628f3d7fe5b90bc8271f4912d7cadb25360a27 + test -z "$(git status --porcelain=v1)" + git fetch origin main --tags + git checkout --detach "$RELEASE_VERSION" + test "$(git rev-parse HEAD)" = "$RELEASE_COMMIT" +) ``` Publish with `pod trunk push Transloadit.podspec` when the Xcode toolchain supports @@ -87,15 +88,17 @@ successful push used a temporary build configuration with Xcode's supported deployment targets and allowed those existing warnings: ```sh -RELEASE_VALIDATION_DIR="$(mktemp -d -t transloaditkit-release)" -cat > "$RELEASE_VALIDATION_DIR/validation.xcconfig" <<'XCCONFIG' +( + set -e + RELEASE_VALIDATION_DIR="$(mktemp -d -t transloaditkit-release)" + trap 'rm -f "$RELEASE_VALIDATION_DIR/validation.xcconfig"; rmdir "$RELEASE_VALIDATION_DIR"' EXIT + cat > "$RELEASE_VALIDATION_DIR/validation.xcconfig" <<'XCCONFIG' IPHONEOS_DEPLOYMENT_TARGET = 15.0 MACOSX_DEPLOYMENT_TARGET = 12.0 XCCONFIG -XCODE_XCCONFIG_FILE="$RELEASE_VALIDATION_DIR/validation.xcconfig" \ - pod trunk push Transloadit.podspec --allow-warnings -rm "$RELEASE_VALIDATION_DIR/validation.xcconfig" -rmdir "$RELEASE_VALIDATION_DIR" + XCODE_XCCONFIG_FILE="$RELEASE_VALIDATION_DIR/validation.xcconfig" \ + pod trunk push Transloadit.podspec --allow-warnings +) ``` This override applies only to the validation build. The published podspec still From 6b1c3c3be0af6a69ea3c216878deda41811829c2 Mon Sep 17 00:00:00 2001 From: Kevin van Zonneveld Date: Wed, 7 Oct 2026 14:31:54 +0200 Subject: [PATCH 3/4] Clarify recovery after pushing a release tag --- CONTRIBUTING.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5cdb832..677c304 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -54,6 +54,11 @@ as the GitHub release body. Continue only after each command block succeeds. Confirm the published release has the expected notes and that the tag points to the merged preparation commit. +If the tag was pushed but GitHub release creation failed, fetch the tags and +confirm `git rev-parse 3.6.0^{commit}` matches the preparation commit. Rerun the +block with the `git tag -a` line omitted. If the release already exists, inspect +it with `gh release view 3.6.0` instead of recreating it. + ### CocoaPods publication Use a macOS machine with Xcode and CocoaPods installed. A pod owner must run From 1487aee2223060d3549cec013d4e974fc5189138 Mon Sep 17 00:00:00 2001 From: Kevin van Zonneveld Date: Wed, 7 Oct 2026 14:39:07 +0200 Subject: [PATCH 4/4] Use a generic macOS publishing machine in release docs --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 677c304..e13512b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -67,8 +67,8 @@ confirm the session through the verification email. Run `pod trunk me` to confirm the session is verified and lists `Transloadit` before pushing. The [3.6.0 release on trunk](https://trunk.cocoapods.org/api/v1/pods/Transloadit/versions/3.6.0) -was published on `studio1` with CocoaPods 1.17.0 and Xcode 27.0. Connect with -`ssh studio1`, then use its clean repository checkout: +was published with CocoaPods 1.17.0 and Xcode 27.0. Use a clean repository checkout +on a macOS machine with Xcode and CocoaPods: ```sh cd ~/code/TransloaditKit && (