diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..6a475b7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,83 @@ +name: Bug report +description: Report a reproducible IPAPatch-Lookin problem +title: "[Bug]: " +labels: + - bug +body: + - type: checkboxes + id: authorization + attributes: + label: Responsible-use confirmation + options: + - label: I am testing an application I own or am authorized to inspect, and I will not attach an IPA, certificate, or provisioning profile. + required: true + + - type: input + id: version + attributes: + label: IPAPatch-Lookin version + description: Run `./ipapatch-lookin --version`. + placeholder: "0.4.2" + validations: + required: true + + - type: textarea + id: environment + attributes: + label: Environment + description: Include macOS, Xcode, Mac architecture, destination type, and iOS version. + placeholder: | + macOS: 15.x + Xcode: 16.x + Mac: Apple silicon + Destination: physical iPhone / iPad or Simulator + iOS: 18.x + validations: + required: true + + - type: textarea + id: ipa_metadata + attributes: + label: IPA metadata + description: Paste only the app name, platform, architectures, and cryptid from `./ipapatch-lookin inspect App.ipa`. Remove private paths and identifiers. + render: text + validations: + required: true + + - type: textarea + id: steps + attributes: + label: Steps to reproduce + placeholder: | + 1. Run ... + 2. Open ... + 3. Select ... + validations: + required: true + + - type: textarea + id: expected + attributes: + label: Expected behavior + validations: + required: true + + - type: textarea + id: actual + attributes: + label: Actual behavior and logs + description: Redact usernames, local paths, device identifiers, team IDs, bundle identifiers, tokens, and signing material. Do not upload an IPA. + render: text + validations: + required: true + + - type: dropdown + id: reproducibility + attributes: + label: Reproducibility + options: + - Every time + - Sometimes + - Once + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..1b5f16c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: false +contact_links: + - name: Documentation and troubleshooting + url: https://github.com/jacklv-coder/IPAPatch-Lookin#troubleshooting + about: Check the requirements, platform notes, and common failure explanations first. + - name: Security vulnerability + url: https://github.com/jacklv-coder/IPAPatch-Lookin/security/advisories/new + about: Report security issues privately instead of opening a public issue. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..a32597a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,39 @@ +name: Feature request +description: Suggest an improvement to an authorized inspection workflow +title: "[Feature]: " +labels: + - enhancement +body: + - type: checkboxes + id: scope + attributes: + label: Scope confirmation + options: + - label: This request supports legitimate development, testing, or authorized inspection. + required: true + + - type: textarea + id: problem + attributes: + label: Problem + description: What workflow is difficult today? + validations: + required: true + + - type: textarea + id: proposal + attributes: + label: Proposed solution + validations: + required: true + + - type: textarea + id: alternatives + attributes: + label: Alternatives considered + + - type: textarea + id: context + attributes: + label: Additional context + description: Do not attach proprietary applications, IPA files, signing material, or other sensitive data. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..279cf00 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,17 @@ +## Summary + +- Describe the user-visible change. +- Explain why it is needed. + +## Validation + +- [ ] `xcrun swift test` +- [ ] `sh -n ipapatch-lookin Tools/patch.sh Tools/verify_patch.sh` +- [ ] `plutil -lint IPAPatch.xcodeproj/project.pbxproj` +- [ ] `git diff --check` + +## Safety and compatibility + +- [ ] No IPA, certificate, provisioning profile, device identifier, or other sensitive material is included. +- [ ] Existing `run`, direct-IPA, and `deploy` behavior remains compatible, or the change is documented. +- [ ] Documentation and tests are updated when user-facing behavior changes. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..ffeac9a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,41 @@ +name: CI + +on: + push: + branches: + - main + pull_request: + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ci-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + validate: + name: Test and validate + runs-on: macos-15 + timeout-minutes: 20 + + steps: + - name: Check out repository + uses: actions/checkout@v7 + + - name: Show toolchain versions + run: | + xcodebuild -version + xcrun swift --version + + - name: Run Swift tests + # Foundation Process tests can leave Swift Testing's parallel runner + # waiting during shutdown on GitHub-hosted macOS runners. + run: xcrun swift test --no-parallel + + - name: Validate shell scripts + run: sh -n ipapatch-lookin Tools/patch.sh Tools/verify_patch.sh + + - name: Validate Xcode project + run: plutil -lint IPAPatch.xcodeproj/project.pbxproj diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..6c22abd --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,21 @@ +# Changelog + +## IPAPatch-Lookin 0.4.2 — 2026-08-20 + +First packaged release of the current IPAPatch-Lookin workflow. + +### Highlights + +- generate or reuse an isolated Xcode project for each byte-distinct IPA; +- accept `./ipapatch-lookin App.ipa` as the primary project-generation command; +- validate IPA encryption state, Mach-O platform, and architecture before use; +- inject the pinned LookinServer 1.2.8 package; +- support physical-device and compatible Simulator workflows; +- redirect declared App Groups into the patched app's sandbox; +- provide bilingual documentation and actionable project-ready output; and +- cover the CLI, project generator, command runner, and Mach-O handling with + automated tests. + +The repository's `1.0` and `1.0.1` tags are historical tags inherited from the +upstream IPAPatch project. Current IPAPatch-Lookin releases use the +`ipapatch-lookin-v` tag prefix to avoid ambiguity. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..fee4268 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,39 @@ +# Contributing to IPAPatch-Lookin + +Thanks for helping improve IPAPatch-Lookin. Contributions should support +applications that contributors own or are authorized to inspect. + +Never commit or attach IPA files, proprietary application code, signing +certificates, provisioning profiles, device identifiers, Apple team IDs, or +other secrets. Use synthetic fixtures and redact local paths and identifiers +from logs. + +## Development + +Requirements: + +- macOS 13 or newer; +- Xcode with its command-line tools selected; and +- Swift 5.9 or newer. + +Run the local validation suite before opening a pull request: + +```sh +xcrun swift test +sh -n ipapatch-lookin Tools/patch.sh Tools/verify_patch.sh +plutil -lint IPAPatch.xcodeproj/project.pbxproj +git diff --check +``` + +Tests that need an IPA must use an application you own or are authorized to +inspect. Do not add that IPA to the repository, an issue, or a pull request. + +## Pull requests + +Keep each pull request focused. Describe the user-visible behavior, list the +validation performed, and update both `README.md` and `README.zh-CN.md` when a +workflow or requirement changes. + +Bug fixes should include a regression test when practical. Changes to project +generation should verify both a newly created project and reuse of an existing +project. diff --git a/README.md b/README.md index 0e63ced..1c12de1 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ # IPAPatch-Lookin +[![CI](https://github.com/jacklv-coder/IPAPatch-Lookin/actions/workflows/ci.yml/badge.svg)](https://github.com/jacklv-coder/IPAPatch-Lookin/actions/workflows/ci.yml) +[![Release](https://img.shields.io/github/v/release/jacklv-coder/IPAPatch-Lookin?display_name=tag)](https://github.com/jacklv-coder/IPAPatch-Lookin/releases/latest) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) +

English | 简体中文

@@ -37,7 +41,7 @@ documentation is preserved in [README_UPSTREAM.md](README_UPSTREAM.md). ## Quick start -Clone the repository and point it at a decrypted IPA: +Clone the repository over SSH and point it at a decrypted IPA: ```sh git clone git@github.com:jacklv-coder/IPAPatch-Lookin.git @@ -45,6 +49,13 @@ cd IPAPatch-Lookin ./ipapatch-lookin ~/Downloads/YourApp.ipa ``` +If you have not configured a GitHub SSH key, use the public HTTPS clone URL +instead: + +```sh +git clone https://github.com/jacklv-coder/IPAPatch-Lookin.git +``` + The command prints a path such as `Projects/YourApp-a1b2c3d4e5f6/IPAPatch.xcodeproj`. Then: diff --git a/README.zh-CN.md b/README.zh-CN.md index 9a540e5..d2427d0 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -1,5 +1,9 @@ # IPAPatch-Lookin +[![CI](https://github.com/jacklv-coder/IPAPatch-Lookin/actions/workflows/ci.yml/badge.svg)](https://github.com/jacklv-coder/IPAPatch-Lookin/actions/workflows/ci.yml) +[![Release](https://img.shields.io/github/v/release/jacklv-coder/IPAPatch-Lookin?display_name=tag)](https://github.com/jacklv-coder/IPAPatch-Lookin/releases/latest) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) +

English | 简体中文

@@ -34,7 +38,7 @@ IPA 与 Mach-O 校验、适配现代签名流程的清理、自动 App Group 重 ## 快速开始 -克隆仓库,并传入一个已解密的 IPA: +通过 SSH 克隆仓库,并传入一个已解密的 IPA: ```sh git clone git@github.com:jacklv-coder/IPAPatch-Lookin.git @@ -42,6 +46,12 @@ cd IPAPatch-Lookin ./ipapatch-lookin ~/Downloads/YourApp.ipa ``` +如果尚未配置 GitHub SSH Key,也可以使用公开的 HTTPS 地址克隆: + +```sh +git clone https://github.com/jacklv-coder/IPAPatch-Lookin.git +``` + 该命令会输出类似 `Projects/YourApp-a1b2c3d4e5f6/IPAPatch.xcodeproj` 的路径。然后: diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..3a3396d --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,21 @@ +# Security policy + +## Supported versions + +Security fixes are made on the `main` branch and included in the newest GitHub +Release. Older snapshots and the historical upstream tags are not supported. + +## Reporting a vulnerability + +Please use GitHub's private vulnerability reporting form: + +https://github.com/jacklv-coder/IPAPatch-Lookin/security/advisories/new + +Do not open a public issue for an undisclosed vulnerability. Do not attach an +IPA, certificate, provisioning profile, device identifier, signing material, +or proprietary application code. Provide the smallest synthetic reproduction +possible and redact local paths, bundle identifiers, and Apple account data. + +The maintainer will acknowledge a report when it is reviewed, coordinate any +needed reproduction privately, and publish remediation details after a fix is +available. diff --git a/Sources/IPAPatchLookinCore/CommandRunner.swift b/Sources/IPAPatchLookinCore/CommandRunner.swift index adfe8f3..00367c6 100644 --- a/Sources/IPAPatchLookinCore/CommandRunner.swift +++ b/Sources/IPAPatchLookinCore/CommandRunner.swift @@ -76,6 +76,12 @@ public enum CommandRunner { process.standardInput = FileHandle.standardInput try process.run() + if captureOutput { + // Process duplicates these descriptors for the child. Close the + // parent's copies so the readers observe EOF when the child exits. + outputPipe.fileHandleForWriting.closeFile() + errorPipe.fileHandleForWriting.closeFile() + } let readGroup = DispatchGroup() let capturedOutput = CapturedData()