make-xcframeworks.sh succeeds with stale outputs after build and signing failures
Nobody has claimed this yet.
- Dominant language
- Swift
- Stars
- 24.6k
- Forks
- 4.2k
- Avg merge
- 5d 6h
- Merged PRs (30d)
- 2
Description
Short description
scripts/make-xcframeworks.sh can return success and create RxSwift.xcframework.zip from stale framework directories even when every build and signing command fails.
Verified against current main, 3e33f90. The script clears .build, but not the output *.xcframework directories. It does not enable failure propagation; xcodebuild is piped to xcbeautify, failed codesign calls do not stop the loop, and the final successful zip determines its exit status.
Isolated reproduction
This runs the script with stubbed build/signing tools and real Bash/zip. It does not run Xcode, access signing credentials, or publish anything. Run from a checkout containing the script:
import os, pathlib, subprocess, tempfile, zipfile
source = pathlib.Path('scripts/make-xcframeworks.sh').read_text()
root = pathlib.Path(tempfile.mkdtemp(prefix='rxswift-release-test-'))
(root / 'make-xcframeworks.sh').write_text(source)
(root / 'bin').mkdir()
for name, body in {
'xcodebuild': 'echo build-failed >&2\nexit 42\n',
'codesign': 'echo sign-failed >&2\nexit 42\n',
'xcbeautify': 'cat\n',
}.items():
p = root / 'bin' / name
p.write_text('#!/bin/sh\n' + body)
p.chmod(0o755)
for name in ['RxSwift', 'RxRelay', 'RxCocoa', 'RxTest', 'RxBlocking']:
d = root / (name + '.xcframework')
d.mkdir()
(d / 'old-build.txt').write_text('previous build fixture\n')
env = {**os.environ, 'PATH': str(root / 'bin') + os.pathsep + os.environ['PATH']}
result = subprocess.run(['bash', 'make-xcframeworks.sh'], cwd=root, env=env,
capture_output=True, text=True)
print('exit:', result.returncode)
print(zipfile.ZipFile(root / 'RxSwift.xcframework.zip').namelist())
Observed on macOS: exit 0, despite 53 failing build calls and five failing signing calls; the ZIP contains all five old-build.txt sentinels.
Expected behavior
Stop with a nonzero status on any required archive/build/signing failure. Use a fresh output directory, propagate pipeline failures, verify the expected framework set and signatures, then create the final ZIP only after those checks succeed. The fixture above should fail before producing a distributable archive.
Release-history check
I reviewed GitHub releases from 2024-09-10 through 2026-09-10. Releases 6.8.0, 6.9.0, 6.9.1, and 6.10.0 each have RxSwift.xcframework.zip; 6.10.1 and 6.10.2 have no uploaded assets, matching the separate report in #2729.
The repository's public Actions inventory contains the test workflow and Dependabot, with no release workflow. That means the available public records do not expose a failed publication attempt, rerun, triggering actor, or manual recovery for those two releases. This repository does not use Changesets for this script.
Scope
The deterministic reproduction establishes a release-script integrity failure: stale output can become a successful archive after build/signing failures. It does not establish that this script caused the missing assets in #2729, that a stale archive was uploaded, or that any production release was manually retried.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with scripts/make-xcframeworks.sh and run the isolated Python reproduction with stubbed xcodebuild, codesign, and xcbeautify. Trace how build, signing, pipeline, output-directory, and ZIP statuses are handled. Done means the fixture exits nonzero and produces no distributable archive when required steps fail, while successful runs verify the expected frameworks and signatures before creating the ZIP.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- bash, swift
- Domain
- release
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100