RepoPilotOpen in app →

nomad-cli/shenzhen

CLI for Building & Distributing iOS Apps (.ipa Files)

Mixed

Stale — last commit 5y ago

worst of 4 axes
Use as dependencyMixed

last commit was 5y ago; no CI workflows detected

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isMixed

last commit was 5y ago; no CI workflows detected

  • 32+ active contributors
  • MIT licensed
  • Tests present
Show 3 more →
  • Stale — last commit 5y ago
  • Concentrated ownership — top contributor handles 57% of recent commits
  • No CI workflows detected
What would change the summary?
  • Use as dependency MixedHealthy if: 1 commit in the last 365 days
  • Deploy as-is MixedHealthy if: 1 commit in the last 180 days

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Forkable" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Forkable
[![RepoPilot: Forkable](https://repopilot.app/api/badge/nomad-cli/shenzhen?axis=fork)](https://repopilot.app/r/nomad-cli/shenzhen)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/nomad-cli/shenzhen on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: nomad-cli/shenzhen

Generated by RepoPilot · 2026-05-10 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/nomad-cli/shenzhen shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

WAIT — Stale — last commit 5y ago

  • 32+ active contributors
  • MIT licensed
  • Tests present
  • ⚠ Stale — last commit 5y ago
  • ⚠ Concentrated ownership — top contributor handles 57% of recent commits
  • ⚠ No CI workflows detected

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live nomad-cli/shenzhen repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/nomad-cli/shenzhen.

What it runs against: a local clone of nomad-cli/shenzhen — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in nomad-cli/shenzhen | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | Last commit ≤ 1815 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>nomad-cli/shenzhen</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of nomad-cli/shenzhen. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/nomad-cli/shenzhen.git
#   cd shenzhen
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of nomad-cli/shenzhen and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "nomad-cli/shenzhen(\\.git)?\\b" \\
  && ok "origin remote is nomad-cli/shenzhen" \\
  || miss "origin remote is not nomad-cli/shenzhen (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 1815 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~1785d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/nomad-cli/shenzhen"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

Shenzhen is a Ruby CLI tool that automates iOS app packaging (.ipa file creation) and distribution to beta testing & app store platforms via a single command-line interface. It wraps Xcode's build system and integrates with 10+ distribution services (HockeyApp, Crashlytics, TestFairy, S3, iTunes Connect, etc.) to eliminate manual Xcode workflows for CI/CD pipelines. Single Ruby gem with modular plugin architecture: lib/shenzhen/commands/ contains build/distribute/info CLI commands; lib/shenzhen/plugins/ contains adapter classes for each distribution target (S3, HockeyApp, iTunes Connect, etc.); lib/shenzhen/xcodebuild.rb and lib/shenzhen/agvtool.rb wrap Xcode toolchain execution; entry point is bin/ipa command-line executable.

👥Who it's for

iOS development teams and DevOps engineers who need to automate build & distribution workflows in CI/CD systems (Jenkins, GitLab CI, etc.) without clicking through Xcode UI or rolling custom build scripts. Particularly teams distributing beta builds to testers and enterprise customers.

🌱Maturity & risk

Abandoned/Legacy: This project uses the deprecated Xcode 6 build API (unsupported for ~3 years as of README notice). No recent commits visible in file metadata. The README explicitly recommends migrating to fastlane/gym for new projects. Not suitable for modern Xcode versions with Swift 3+, watchOS, or multi-target apps.

High risk for new adoption: Xcode 6 API deprecation breaks compatibility with modern Swift and app target features. Single-language Ruby codebase (63K lines) with no visible test suite in file list. Unmaintained status means zero support for Xcode 15+, Apple Silicon, or modern iOS deployment. Only use for legacy projects already running on old Xcode versions.

Active areas of work

Project is in maintenance mode with no active development. README explicitly directs users to fastlane/gym as maintained alternatives. No ongoing work visible in file structure.

🚀Get running

gem install shenzhen
ipa build --workspace MyApp.xcworkspace --scheme MyScheme
ipa distribute:hockeyapp --file MyApp.ipa --token YOUR_TOKEN

Daily commands: Install with gem install shenzhen, then invoke ipa build to create .ipa or ipa distribute:SERVICE_NAME to push to distribution platform. Set LC_ALL="en_US.UTF-8" environment variable to avoid ASCII encoding errors.

🗺️Map of the codebase

  • bin/ipa: Entry point executable that users invoke; handles CLI argument parsing and command routing
  • lib/shenzhen/commands/build.rb: Core build command that invokes xcodebuild and creates .ipa files; where most Xcode-specific logic lives
  • lib/shenzhen/commands/distribute.rb: Routes .ipa files to distribution services via plugin system; orchestrates uploads to HockeyApp, S3, iTunes Connect, etc.
  • lib/shenzhen/xcodebuild.rb: Wraps Xcode's command-line tools (xcodebuild, xcrun) to compile source and package .ipa; most fragile code due to API deprecation
  • lib/shenzhen/plugins/: Directory containing adapter classes for each distribution platform; add new files here to support additional services
  • lib/shenzhen.rb: Main module that loads and initializes all commands and plugins

🛠️How to make changes

To add a new distribution service: create lib/shenzhen/plugins/myservice.rb with a class inheriting from base plugin; implement validate and upload methods; register in lib/shenzhen/commands/distribute.rb. To modify build logic: edit lib/shenzhen/commands/build.rb or extend lib/shenzhen/xcodebuild.rb for Xcode integration.

🪤Traps & gotchas

Critical: Requires old Xcode 6 era build system; will fail on modern Xcode versions. Must set LC_ALL="en_US.UTF-8" environment variable or random 'invalid byte sequence in US-ASCII' errors occur. Each distribution plugin (HockeyApp, Crashlytics, S3) requires separate API credentials/tokens passed as CLI arguments. Xcode 5.1 users need special ARCHFLAGS workaround to install json gem dependency. No built-in validation of .ipa file format before upload.

💡Concepts to learn

  • IPA File Format — Shenzhen's core purpose is creating and distributing .ipa files; understanding that they are ZIP archives containing compiled binary, resources, and metadata is essential to debugging build failures
  • Xcode Build System (Legacy) — Shenzhen wraps xcodebuild CLI tool which uses the deprecated Xcode 6 build system; understanding build phases, targets, and schemes is necessary to configure .ipa generation correctly
  • Code Signing & Provisioning Profiles — Build and distribute commands require valid code signing identity and provisioning profiles; misconfigurations here are the most common failure cause in Shenzhen workflows
  • Plugin Architecture Pattern — Shenzhen uses adapter pattern with pluggable distribution backends; understanding how lib/shenzhen/plugins/ classes inherit from base and override upload() is key to extending or modifying distribution targets
  • Shell Command Execution Safety — Shenzhen invokes xcodebuild, agvtool, and PlistBuddy via backticks/shell; understanding escaping pitfalls and exit code handling is critical when modifying xcodebuild.rb to avoid injection vulnerabilities
  • App Store Connect / iTunes Connect API — The iTunes Connect plugin (lib/shenzhen/plugins/itunesconnect.rb) automates TestFlight uploads; understanding Apple's OAuth/credentials flow is necessary to troubleshoot authentication failures
  • CI/CD Pipeline Integration — Shenzhen is designed for automation in Jenkins/GitLab/GitHub Actions; understanding how to securely pass API tokens via environment variables and handle build artifacts is essential to production usage
  • fastlane/fastlane — Modern maintained replacement for Shenzhen; gym handles .ipa building with current Xcode API, fastlane handles distribution to same platforms
  • fastlane/gym — Standalone successor to Shenzhen's build command; uses modern Xcode APIs and supports Swift 3+, watchOS, multi-target projects
  • nomad/cupertino — Companion CLI tool in same nomad series for Apple Dev Center account management; often used alongside Shenzhen for provisioning profiles
  • nomad/houston — Sister project in nomad CLI utilities series for managing iOS push notifications; complements Shenzhen distribution workflows
  • nomad/venice — Another nomad CLI tool for In-App Purchase receipt verification; part of same iOS development utility ecosystem

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add integration tests for distribution plugins (Crashlytics, HockeyApp, S3, etc.)

The repo has 9 distribution plugins in lib/shenzhen/plugins/ but no test coverage for their upload/distribution logic. Given the critical nature of distributing iOS apps, adding integration tests with mocked API responses would catch regressions when plugins break due to API changes (which happens frequently with third-party services). This is especially valuable since some of these services may have changed their APIs in the 3+ years since this repo was last actively maintained.

  • [ ] Create test/integration directory structure
  • [ ] Add tests for lib/shenzhen/plugins/crashlytics.rb using webmock or VCR to mock API responses
  • [ ] Add tests for lib/shenzhen/plugins/hockeyapp.rb with upload/distribution scenarios
  • [ ] Add tests for lib/shenzhen/plugins/s3.rb with AWS credentials and bucket operations
  • [ ] Document how to run integration tests in README.md

Refactor lib/shenzhen/commands/build.rb to extract xcodebuild configuration into a dedicated builder module

The build.rb command file likely contains complex xcodebuild orchestration logic mixed with CLI argument parsing. Extracting this into lib/shenzhen/builders/xcode_builder.rb would improve testability and maintainability, making it easier for contributors to understand the build pipeline. This follows the pattern already established by lib/shenzhen/xcodebuild.rb and would reduce cognitive load.

  • [ ] Analyze lib/shenzhen/commands/build.rb to identify xcodebuild configuration logic
  • [ ] Create lib/shenzhen/builders/xcode_builder.rb to encapsulate build configuration and execution
  • [ ] Move build scheme validation, provisioning profile resolution, and xcodebuild invocation to the builder
  • [ ] Update lib/shenzhen/commands/build.rb to use the new builder module
  • [ ] Add unit tests for lib/shenzhen/builders/xcode_builder.rb

Add GitHub Actions workflow for testing against multiple macOS + Xcode versions

Shenzhen depends heavily on Xcode APIs and tools (xcodebuild, agvtool, plistbuddy). Without CI, breaking changes in Xcode or Ruby versions go undetected. A GitHub Actions workflow testing against macOS 11/12/13 with Xcode 12/13/14/15 would help catch compatibility regressions, especially important given the README's warning that the codebase uses deprecated Xcode 6 APIs.

  • [ ] Create .github/workflows/test.yml with macOS runner matrix
  • [ ] Test against Xcode 12, 13, 14, and 15 (latest stable versions)
  • [ ] Run bundle install && rake test (or equivalent from Rakefile)
  • [ ] Add build status badge to README.md
  • [ ] Document in CONTRIBUTING.md how to test locally across Xcode versions

🌿Good first issues

  • Add test suite: Create spec/ directory with RSpec tests for lib/shenzhen/xcodebuild.rb command construction and lib/shenzhen/commands/build.rb build flow (currently no test files visible)
  • Document plugin template: Create PLUGIN_DEVELOPMENT.md with step-by-step guide to adding new distribution service, including minimal code example and required interface methods (currently only discoverable by reading existing plugins)
  • Add support for new distribution target: Implement S3-compatible alternative (e.g., MinIO, Wasabi) in new lib/shenzhen/plugins/s3compatible.rb file, copying pattern from existing lib/shenzhen/plugins/s3.rb but with configurable endpoint URL

Top contributors

Click to expand

📝Recent commits

Click to expand
  • b745dc2 — Update README.md (mattt)
  • 06f0e9c — Build command: update Xcode version validation for Xcode 10+ (#351) (#352) (thzinc)
  • e9de171 — Escape arguments (#342) (dankimio)
  • b0b6d71 — Update fir API (#289) (xuanyu-h)
  • 2ef65bb — Pgyer: fix shortcutURL (#333) (shishirui)
  • cf2d982 — Version 0.14.3 (dankimio)
  • f677214 — Rakefile: use Bundler gem tasks (dankimio)
  • 3bba30f — Add more information about the state of the project (#340) (KrauseFx)
  • 0fefe03 — Fixed issue with search path containing spaces to security command (#273) (aenglund)
  • 06abb7b — README: fix fir.im command name (#295) (kemingcao)

🔒Security observations

The Shenzhen CLI tool presents several security concerns that warrant immediate attention. The most critical issue is the use of a deprecated Xcode 6 API that no longer receives security updates. The multiple distribution plugins handling sensitive credentials present a high risk if not properly implemented with secure credential storage. Command injection vulnerabilities are likely present due to shell command execution without apparent input validation. The FTP plugin uses an unencrypted protocol. The project appears to lack proper input validation mechanisms, audit logging, and secure credential management practices. Migration to modern alternatives like fastlane/gym is strongly recommended per the project's own

  • High · Deprecated Xcode Build API — lib/shenzhen/xcodebuild.rb, lib/shenzhen/commands/build.rb. The project uses the Xcode 6 build API which has been deprecated for nearly 3 years. This API is outdated and may lack critical security patches, bug fixes, and support for modern iOS development practices. It also has compatibility issues with Swift 3, watchOS, and other app targets. Fix: Migrate to gym (fastlane/gym) which uses the latest Xcode API and receives active maintenance and security updates.
  • High · Multiple Distribution Plugins with Potential Credential Exposure — lib/shenzhen/plugins/. The codebase includes multiple distribution plugins (crashlytics, deploygate, fir, ftp, hockeyapp, itunesconnect, pgyer, s3, testfairy) that likely handle API keys, tokens, and credentials. Without reviewing the implementation details, these plugins present a risk of credential exposure, hardcoded secrets, or insecure credential storage. Fix: Audit each plugin for: (1) hardcoded credentials, (2) secure credential storage using environment variables or credential managers, (3) proper error handling that doesn't leak sensitive data, (4) use of HTTPS/TLS for all communications.
  • High · Command Execution Without Input Validation — lib/shenzhen/xcodebuild.rb, lib/shenzhen/agvtool.rb, lib/shenzhen/plistbuddy.rb, lib/shenzhen/commands/build.rb. The project heavily uses system command execution (xcodebuild, agvtool, plistbuddy) via shell interfaces. If user input (app name, version, paths) is not properly sanitized before being passed to shell commands, this could allow command injection attacks. Fix: Implement strict input validation and sanitization. Use parameterized command execution instead of string interpolation in shell commands. Use libraries like Shellwords to safely escape shell arguments.
  • Medium · No Visible Security Headers or Input Validation — lib/shenzhen/commands/distribute.rb, lib/shenzhen/commands/build.rb. Review of file structure shows no obvious input validation mechanisms or security policy enforcement in the commands module. Distribution commands may accept user input that requires validation. Fix: Implement comprehensive input validation for all user-supplied parameters. Validate file paths, URLs, email addresses, and credentials.
  • Medium · Potential FTP Plugin Security Issues — lib/shenzhen/plugins/ftp.rb. FTP is an unencrypted protocol that transmits credentials and data in plaintext. Using FTP for distributing iOS apps exposes sensitive information to network eavesdropping. Fix: Prefer SFTP or other encrypted protocols for file distribution. If FTP must be supported, document the security implications and recommend SFTP as the preferred method.
  • Medium · Missing Dependency Management Visibility — Gemfile, shenzhen.gemspec. The Gemfile content is not provided, making it impossible to assess if the project uses vulnerable gem versions. Ruby dependencies should be regularly audited. Fix: Run 'bundle audit' regularly to check for vulnerable gems. Pin gem versions appropriately. Keep dependencies up to date. Consider using Dependabot or similar tools for automated vulnerability tracking.
  • Low · Lack of Audit Logging — lib/shenzhen/commands/distribute.rb. No visible audit logging mechanism for distribution actions. This makes it difficult to track who distributed what app and when, which is important for compliance and security investigations. Fix: Implement comprehensive audit logging for all distribution actions including: user identity, timestamp, app version, distribution method, and result.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Mixed signals · nomad-cli/shenzhen — RepoPilot