shippilot 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/LICENSE +21 -0
- package/README.md +241 -0
- package/dist/auth/prepareCodexHome.d.ts +7 -0
- package/dist/auth/prepareCodexHome.js +52 -0
- package/dist/auth/prepareCodexHome.js.map +1 -0
- package/dist/auth/validateAuth.d.ts +2 -0
- package/dist/auth/validateAuth.js +19 -0
- package/dist/auth/validateAuth.js.map +1 -0
- package/dist/cases/parseCase.d.ts +13 -0
- package/dist/cases/parseCase.js +21 -0
- package/dist/cases/parseCase.js.map +1 -0
- package/dist/cases/resolveEnv.d.ts +6 -0
- package/dist/cases/resolveEnv.js +19 -0
- package/dist/cases/resolveEnv.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +219 -0
- package/dist/cli.js.map +1 -0
- package/dist/codex/outputSchema.d.ts +72 -0
- package/dist/codex/outputSchema.js +48 -0
- package/dist/codex/outputSchema.js.map +1 -0
- package/dist/codex/promptBuilder.d.ts +8 -0
- package/dist/codex/promptBuilder.js +48 -0
- package/dist/codex/promptBuilder.js.map +1 -0
- package/dist/codex/runWithSdk.d.ts +11 -0
- package/dist/codex/runWithSdk.js +396 -0
- package/dist/codex/runWithSdk.js.map +1 -0
- package/dist/config/loadConfig.d.ts +2 -0
- package/dist/config/loadConfig.js +13 -0
- package/dist/config/loadConfig.js.map +1 -0
- package/dist/config/schema.d.ts +43 -0
- package/dist/config/schema.js +71 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/exitCodes.d.ts +7 -0
- package/dist/exitCodes.js +7 -0
- package/dist/exitCodes.js.map +1 -0
- package/dist/ios/doctorXcode.d.ts +3 -0
- package/dist/ios/doctorXcode.js +33 -0
- package/dist/ios/doctorXcode.js.map +1 -0
- package/dist/ios/xcodebuildmcp.d.ts +15 -0
- package/dist/ios/xcodebuildmcp.js +95 -0
- package/dist/ios/xcodebuildmcp.js.map +1 -0
- package/dist/reports/jsonReport.d.ts +11 -0
- package/dist/reports/jsonReport.js +27 -0
- package/dist/reports/jsonReport.js.map +1 -0
- package/dist/reports/junitReport.d.ts +4 -0
- package/dist/reports/junitReport.js +39 -0
- package/dist/reports/junitReport.js.map +1 -0
- package/dist/reports/markdownReport.d.ts +4 -0
- package/dist/reports/markdownReport.js +46 -0
- package/dist/reports/markdownReport.js.map +1 -0
- package/dist/security/redact.d.ts +5 -0
- package/dist/security/redact.js +12 -0
- package/dist/security/redact.js.map +1 -0
- package/docs/auth.md +47 -0
- package/docs/bitrise.md +22 -0
- package/docs/github-actions.md +47 -0
- package/docs/personal-chatgpt-subscription.md +31 -0
- package/docs/plan.md +55 -0
- package/docs/release.md +87 -0
- package/docs/security.md +39 -0
- package/examples/bitrise/shippilot.sh +6 -0
- package/examples/github-actions/shippilot.yml +39 -0
- package/examples/qa/login.md +15 -0
- package/examples/shippilot.yml +24 -0
- package/package.json +51 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Personal ChatGPT Subscription
|
|
2
|
+
|
|
3
|
+
The clean hosted-CI path is `OPENAI_API_KEY`. Personal ChatGPT subscription auth is browser/session based and is not a first-class hosted CI credential.
|
|
4
|
+
|
|
5
|
+
ShipPilot supports one experimental hosted-runner path:
|
|
6
|
+
|
|
7
|
+
1. Log in locally:
|
|
8
|
+
```bash
|
|
9
|
+
codex login
|
|
10
|
+
codex login status
|
|
11
|
+
```
|
|
12
|
+
2. Archive your Codex home:
|
|
13
|
+
```bash
|
|
14
|
+
tar -czf codex-home.tgz ~/.codex
|
|
15
|
+
base64 -i codex-home.tgz | pbcopy
|
|
16
|
+
```
|
|
17
|
+
3. Store the result as `CODEX_HOME_TGZ_BASE64` in GitHub Secrets.
|
|
18
|
+
4. Enable:
|
|
19
|
+
```yaml
|
|
20
|
+
codex:
|
|
21
|
+
auth: chatgpt_hosted_experimental
|
|
22
|
+
allow_experimental_personal_hosted_auth: true
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Warnings:
|
|
26
|
+
|
|
27
|
+
- The login can expire.
|
|
28
|
+
- The auth storage format can change.
|
|
29
|
+
- Treat `CODEX_HOME_TGZ_BASE64` like a highly sensitive credential.
|
|
30
|
+
- Never use this on untrusted fork PRs.
|
|
31
|
+
- Never upload `.codex`, `auth.json`, restored auth folders, or temporary archives.
|
package/docs/plan.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# ShipPilot Full Project Plan
|
|
2
|
+
|
|
3
|
+
ShipPilot is an SDK-first agentic iOS QA runner. Teams write Markdown QA cases, configure an iOS project and simulator, choose a Codex auth mode, and run the tool from GitHub Actions, Bitrise, or local CI. Codex drives the app through an iOS simulator, verifies expected outcomes, captures screenshots/logs, writes reports, and fails CI when a case fails.
|
|
4
|
+
|
|
5
|
+
## Core Design
|
|
6
|
+
|
|
7
|
+
- TypeScript/Node CLI published as `shippilot`.
|
|
8
|
+
- Product name: ShipPilot.
|
|
9
|
+
- GitHub repo: `mahmoudashraf93/ShipPilot`.
|
|
10
|
+
- Primary engine: `@openai/codex-sdk`.
|
|
11
|
+
- iOS automation backend: XcodeBuildMCP CLI.
|
|
12
|
+
- v1 is test-and-report only: no edits, commits, patches, pushes, or PR creation.
|
|
13
|
+
- `codex app-server` is reserved for future advanced integrations.
|
|
14
|
+
|
|
15
|
+
## CLI
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npx shippilot init
|
|
19
|
+
npx shippilot doctor
|
|
20
|
+
npx shippilot run --case qa/login.md
|
|
21
|
+
npx shippilot run --cases qa/
|
|
22
|
+
npx shippilot report --run .shippilot/run.json
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Auth Modes
|
|
26
|
+
|
|
27
|
+
- `api_key`: uses `OPENAI_API_KEY`, recommended for hosted CI.
|
|
28
|
+
- `access_token`: uses `CODEX_ACCESS_TOKEN`, recommended for trusted Business/Enterprise automation.
|
|
29
|
+
- `chatgpt_hosted_experimental`: restores a pre-authenticated Codex home from `CODEX_HOME_TGZ_BASE64`; fragile and not recommended for fork PRs.
|
|
30
|
+
|
|
31
|
+
## CI Semantics
|
|
32
|
+
|
|
33
|
+
- `passed` exits `0`.
|
|
34
|
+
- `failed` exits `1`.
|
|
35
|
+
- setup/auth/config/simulator errors exit `2`.
|
|
36
|
+
- `blocked` exits `3`.
|
|
37
|
+
|
|
38
|
+
`codex.fail_on: never` enables report-only mode.
|
|
39
|
+
|
|
40
|
+
`codex.verbose: true` or `shippilot run --verbose` streams build output and Codex SDK events for CI debugging. It shows reasoning summaries and tool activity, not private chain-of-thought.
|
|
41
|
+
|
|
42
|
+
For simulator UI automation, `codex.sandbox: danger-full-access` is required because XcodeBuildMCP must communicate with CoreSimulator services outside the repository workspace.
|
|
43
|
+
|
|
44
|
+
## Milestones
|
|
45
|
+
|
|
46
|
+
1. Create public repo and initial docs.
|
|
47
|
+
2. Scaffold TypeScript CLI.
|
|
48
|
+
3. Implement config and QA case parsing.
|
|
49
|
+
4. Implement auth validation and redaction.
|
|
50
|
+
5. Implement XcodeBuildMCP doctor checks.
|
|
51
|
+
6. Implement Codex SDK execution.
|
|
52
|
+
7. Implement reports and exit codes.
|
|
53
|
+
8. Add GitHub Actions and Bitrise examples.
|
|
54
|
+
9. Add sample iOS app and smoke cases.
|
|
55
|
+
10. Publish initial npm package as `shippilot`.
|
package/docs/release.md
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Release Process
|
|
2
|
+
|
|
3
|
+
This document describes how to release ShipPilot to npm.
|
|
4
|
+
|
|
5
|
+
## Versioning
|
|
6
|
+
|
|
7
|
+
ShipPilot uses npm semantic versions and git tags prefixed with `v`.
|
|
8
|
+
|
|
9
|
+
For a release, keep these values in sync:
|
|
10
|
+
|
|
11
|
+
- `package.json`
|
|
12
|
+
- `package-lock.json`
|
|
13
|
+
- `src/cli.ts`
|
|
14
|
+
|
|
15
|
+
For example, `0.0.1` is released from git tag `v0.0.1`.
|
|
16
|
+
|
|
17
|
+
## First npm Publish
|
|
18
|
+
|
|
19
|
+
The first release of an unscoped package must create the package on npm before trusted publishing can be configured.
|
|
20
|
+
|
|
21
|
+
For `v0.0.1`, publish once manually from a clean checkout with an npm account that has 2FA enabled:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm login
|
|
25
|
+
npm whoami
|
|
26
|
+
npm ci
|
|
27
|
+
npm run typecheck
|
|
28
|
+
npm test
|
|
29
|
+
npm pack --dry-run
|
|
30
|
+
npm publish --access public
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
If `npm whoami` fails with `ENEEDAUTH`, complete `npm login` first and rerun `npm whoami` before publishing.
|
|
34
|
+
|
|
35
|
+
If `npm publish` fails with `E403` saying two-factor authentication or a granular access token with bypass 2FA is required, enable 2FA on the npm account and rerun `npm publish --access public`. Alternatively, create a granular npm access token with publish access to `shippilot` and bypass 2FA enabled, then publish with `NODE_AUTH_TOKEN` set for that command.
|
|
36
|
+
|
|
37
|
+
After npm publishes `shippilot@0.0.1`, confirm:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npm view shippilot version
|
|
41
|
+
npx shippilot --version
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Both commands should report `0.0.1`.
|
|
45
|
+
|
|
46
|
+
## Configure Trusted Publishing
|
|
47
|
+
|
|
48
|
+
After the first package exists on npm, configure trusted publishing for future releases.
|
|
49
|
+
|
|
50
|
+
On npmjs.com, configure:
|
|
51
|
+
|
|
52
|
+
- Package: `shippilot`
|
|
53
|
+
- Publisher: GitHub Actions
|
|
54
|
+
- Organization or user: `mahmoudashraf93`
|
|
55
|
+
- Repository: `ShipPilot`
|
|
56
|
+
- Workflow filename: `release.yml`
|
|
57
|
+
- Allowed action: `npm publish`
|
|
58
|
+
|
|
59
|
+
The release workflow uses GitHub OIDC with `id-token: write`, so no long-lived `NPM_TOKEN` is required for future publishes.
|
|
60
|
+
|
|
61
|
+
## Future Releases
|
|
62
|
+
|
|
63
|
+
For each future release:
|
|
64
|
+
|
|
65
|
+
1. Update the package version, lockfile version, CLI version, and changelog.
|
|
66
|
+
2. Run local checks:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
npm run typecheck
|
|
70
|
+
npm test
|
|
71
|
+
npm pack --dry-run --json
|
|
72
|
+
npm run build
|
|
73
|
+
node dist/cli.js --version
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
3. Commit the release prep.
|
|
77
|
+
4. Push `main`.
|
|
78
|
+
5. Create and publish a GitHub Release with a tag matching the package version, for example `v0.0.2`.
|
|
79
|
+
6. Confirm the `Release` workflow completed and published the npm package.
|
|
80
|
+
7. Verify:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
npm view shippilot version
|
|
84
|
+
npx shippilot --version
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
The GitHub Release must be published, not saved as a draft, because `.github/workflows/release.yml` runs on `release.published`.
|
package/docs/security.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Security
|
|
2
|
+
|
|
3
|
+
ShipPilot is designed for open-source CI, so secret handling is strict by default.
|
|
4
|
+
|
|
5
|
+
## Defaults
|
|
6
|
+
|
|
7
|
+
- Do not run secret-backed workflows on arbitrary fork PRs.
|
|
8
|
+
- Use `actions/checkout` with `persist-credentials: false`.
|
|
9
|
+
- Do not cache Codex auth by default.
|
|
10
|
+
- Keep auth material in temporary directories.
|
|
11
|
+
- Upload reports with `if: always()`, but never upload auth folders.
|
|
12
|
+
|
|
13
|
+
## Redaction
|
|
14
|
+
|
|
15
|
+
Values declared in QA case `required_env` are redacted from:
|
|
16
|
+
|
|
17
|
+
- generated prompts
|
|
18
|
+
- SDK output
|
|
19
|
+
- logs
|
|
20
|
+
- Markdown reports
|
|
21
|
+
- JSON reports
|
|
22
|
+
- JUnit reports
|
|
23
|
+
|
|
24
|
+
## Never Upload
|
|
25
|
+
|
|
26
|
+
- restored `CODEX_HOME`
|
|
27
|
+
- `.codex`
|
|
28
|
+
- `auth.json`
|
|
29
|
+
- API keys
|
|
30
|
+
- access tokens
|
|
31
|
+
- restored auth archives
|
|
32
|
+
|
|
33
|
+
## Test Scope
|
|
34
|
+
|
|
35
|
+
v1 is test-and-report only. It instructs Codex not to edit source files, create patches, commit, push, or open pull requests.
|
|
36
|
+
|
|
37
|
+
## Simulator Sandbox
|
|
38
|
+
|
|
39
|
+
XcodeBuildMCP needs access to CoreSimulator services outside the repository workspace. For iOS simulator UI automation, set `codex.sandbox: danger-full-access` and run only in trusted CI contexts such as `workflow_dispatch`, release, schedule, or maintainer-approved workflows.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: ShipPilot QA
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
release:
|
|
6
|
+
types: [published]
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
shippilot:
|
|
10
|
+
runs-on: macos-15
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v5
|
|
16
|
+
with:
|
|
17
|
+
persist-credentials: false
|
|
18
|
+
|
|
19
|
+
- uses: actions/setup-node@v4
|
|
20
|
+
with:
|
|
21
|
+
node-version: 22
|
|
22
|
+
|
|
23
|
+
- name: Run ShipPilot
|
|
24
|
+
env:
|
|
25
|
+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
|
26
|
+
CODEX_ACCESS_TOKEN: ${{ secrets.CODEX_ACCESS_TOKEN }}
|
|
27
|
+
CODEX_HOME_TGZ_BASE64: ${{ secrets.CODEX_HOME_TGZ_BASE64 }}
|
|
28
|
+
TEST_EMAIL: ${{ secrets.TEST_EMAIL }}
|
|
29
|
+
TEST_PASSWORD: ${{ secrets.TEST_PASSWORD }}
|
|
30
|
+
run: |
|
|
31
|
+
npx shippilot doctor
|
|
32
|
+
npx shippilot run --case qa/login.md
|
|
33
|
+
|
|
34
|
+
- name: Upload ShipPilot report
|
|
35
|
+
if: always()
|
|
36
|
+
uses: actions/upload-artifact@v4
|
|
37
|
+
with:
|
|
38
|
+
name: shippilot-report
|
|
39
|
+
path: .shippilot/
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: login-happy-path
|
|
3
|
+
title: Login happy path
|
|
4
|
+
required_env:
|
|
5
|
+
- TEST_EMAIL
|
|
6
|
+
- TEST_PASSWORD
|
|
7
|
+
tags:
|
|
8
|
+
- release
|
|
9
|
+
- smoke
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
Launch the app.
|
|
13
|
+
Enter `${TEST_EMAIL}` and `${TEST_PASSWORD}`.
|
|
14
|
+
Tap Log In.
|
|
15
|
+
Expect the Home screen to be visible.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
codex:
|
|
2
|
+
engine: sdk
|
|
3
|
+
auth: api_key
|
|
4
|
+
model: default
|
|
5
|
+
sandbox: danger-full-access
|
|
6
|
+
fail_on: failed_or_blocked
|
|
7
|
+
verbose: false
|
|
8
|
+
allow_experimental_personal_hosted_auth: false
|
|
9
|
+
|
|
10
|
+
ios:
|
|
11
|
+
project: MyApp.xcodeproj
|
|
12
|
+
bundle_id:
|
|
13
|
+
scheme: MyApp
|
|
14
|
+
simulator: iPhone 17 Pro
|
|
15
|
+
backend: xcodebuildmcp
|
|
16
|
+
configuration: Debug
|
|
17
|
+
|
|
18
|
+
reports:
|
|
19
|
+
output_dir: .shippilot
|
|
20
|
+
markdown: true
|
|
21
|
+
json: true
|
|
22
|
+
junit: true
|
|
23
|
+
screenshots: true
|
|
24
|
+
logs: true
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "shippilot",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Agentic iOS QA runner for Codex, GitHub Actions, and Bitrise",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Mahmoud Ashraf",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/mahmoudashraf93/ShipPilot.git"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/mahmoudashraf93/ShipPilot#readme",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/mahmoudashraf93/ShipPilot/issues"
|
|
15
|
+
},
|
|
16
|
+
"bin": {
|
|
17
|
+
"shippilot": "./dist/cli.js"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"examples",
|
|
22
|
+
"docs",
|
|
23
|
+
"CHANGELOG.md",
|
|
24
|
+
"README.md",
|
|
25
|
+
"LICENSE"
|
|
26
|
+
],
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=20"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "tsc -p tsconfig.json",
|
|
32
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
33
|
+
"test": "vitest run",
|
|
34
|
+
"lint": "tsc -p tsconfig.json --noEmit",
|
|
35
|
+
"prepack": "npm run build"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@openai/codex-sdk": "^0.135.0",
|
|
39
|
+
"commander": "^14.0.2",
|
|
40
|
+
"fast-glob": "^3.3.3",
|
|
41
|
+
"gray-matter": "^4.0.3",
|
|
42
|
+
"xcodebuildmcp": "^2.5.2",
|
|
43
|
+
"yaml": "^2.8.1",
|
|
44
|
+
"zod": "^4.1.13"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@types/node": "^24.10.1",
|
|
48
|
+
"typescript": "^5.9.3",
|
|
49
|
+
"vitest": "^4.0.14"
|
|
50
|
+
}
|
|
51
|
+
}
|