@daemux/store-automator 0.9.1 → 0.10.0
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/.claude-plugin/marketplace.json +3 -3
- package/README.md +5 -23
- package/bin/cli.mjs +7 -66
- package/package.json +1 -2
- package/plugins/store-automator/.claude-plugin/plugin.json +1 -1
- package/plugins/store-automator/agents/architect.md +1 -1
- package/plugins/store-automator/agents/devops.md +28 -75
- package/plugins/store-automator/agents/product-manager.md +5 -5
- package/scripts/check_changed.sh +1 -1
- package/src/ci-config.mjs +0 -10
- package/src/install-paths.mjs +1 -75
- package/src/install.mjs +8 -19
- package/src/mcp-setup.mjs +1 -35
- package/src/prompt.mjs +1 -19
- package/src/templates.mjs +0 -1
- package/src/uninstall.mjs +0 -4
- package/src/utils.mjs +0 -9
- package/templates/CLAUDE.md.template +18 -18
- package/templates/ci.config.yaml.template +0 -11
- package/templates/fastlane/android/Fastfile.template +2 -2
- package/templates/fastlane/android/Pluginfile.template +1 -1
- package/templates/fastlane/ios/Fastfile.template +2 -2
- package/templates/fastlane/ios/Pluginfile.template +1 -1
- package/templates/fastlane/ios/Snapfile.template +1 -1
- package/templates/github/workflows/android-release.yml +0 -4
- package/templates/github/workflows/ios-release.yml +0 -4
- package/templates/scripts/check_changed.sh +1 -1
- package/templates/scripts/ci/android/update-data-safety.sh +21 -8
- package/templates/scripts/ci/common/link-fastlane.sh +1 -1
- package/templates/scripts/ci/common/read-config.sh +1 -5
- package/templates/scripts/update_data_safety.py +14 -10
- package/scripts/codemagic-setup.mjs +0 -44
- package/scripts/generate.sh +0 -107
- package/src/codemagic-api.mjs +0 -75
- package/src/codemagic-setup.mjs +0 -190
- package/src/github-setup.mjs +0 -43
- package/templates/codemagic.template.yaml +0 -551
- package/templates/github/workflows/codemagic-trigger.yml +0 -78
- package/templates/scripts/generate.sh +0 -107
|
@@ -5,15 +5,15 @@
|
|
|
5
5
|
},
|
|
6
6
|
"metadata": {
|
|
7
7
|
"description": "App Store & Google Play automation for Flutter apps",
|
|
8
|
-
"version": "0.
|
|
8
|
+
"version": "0.10.0"
|
|
9
9
|
},
|
|
10
10
|
"plugins": [
|
|
11
11
|
{
|
|
12
12
|
"name": "store-automator",
|
|
13
13
|
"source": "./plugins/store-automator",
|
|
14
14
|
"description": "3 agents for app store publishing: reviewer, meta-creator, media-designer",
|
|
15
|
-
"version": "0.
|
|
16
|
-
"keywords": ["flutter", "app-store", "google-play", "fastlane"
|
|
15
|
+
"version": "0.10.0",
|
|
16
|
+
"keywords": ["flutter", "app-store", "google-play", "fastlane"]
|
|
17
17
|
}
|
|
18
18
|
]
|
|
19
19
|
}
|
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ This package installs three Claude Code agents and a complete CI/CD template sui
|
|
|
10
10
|
- **appstore-meta-creator** -- Creates all store metadata texts (names, descriptions, keywords) for all available languages
|
|
11
11
|
- **app-designer** -- Designs complete app UI, creates ASO-optimized store screenshots, and designs marketing web pages — all in Stitch MCP
|
|
12
12
|
|
|
13
|
-
Plus CI/CD templates for
|
|
13
|
+
Plus CI/CD templates for GitHub Actions, Fastlane, web pages, and scripts.
|
|
14
14
|
|
|
15
15
|
## Requirements
|
|
16
16
|
|
|
@@ -27,8 +27,8 @@ npm install @daemux/store-automator@latest
|
|
|
27
27
|
|
|
28
28
|
The postinstall script will:
|
|
29
29
|
|
|
30
|
-
1. Prompt for bundle ID and MCP server tokens (Stitch, Cloudflare
|
|
31
|
-
2. Configure `.mcp.json` with MCP servers (Playwright, mobile-mcp, Stitch, Cloudflare
|
|
30
|
+
1. Prompt for bundle ID and MCP server tokens (Stitch, Cloudflare)
|
|
31
|
+
2. Configure `.mcp.json` with MCP servers (Playwright, mobile-mcp, Stitch, Cloudflare)
|
|
32
32
|
3. Install the plugin marketplace and register agents
|
|
33
33
|
4. Copy `CLAUDE.md` template to `.claude/CLAUDE.md`
|
|
34
34
|
5. Copy CI/CD templates (Fastlane, scripts, web pages, ci.config.yaml)
|
|
@@ -86,8 +86,6 @@ The package installs these templates to your project:
|
|
|
86
86
|
| File | Purpose |
|
|
87
87
|
|------|---------|
|
|
88
88
|
| `ci.config.yaml` | Per-project configuration (credentials, app identity, settings) |
|
|
89
|
-
| `ci-templates/codemagic.template.yaml` | Full Codemagic CI/CD pipeline template |
|
|
90
|
-
| `scripts/generate.sh` | Generates `codemagic.yaml` from template + config |
|
|
91
89
|
| `scripts/check_changed.sh` | Git-based change detection for conditional uploads |
|
|
92
90
|
| `scripts/manage_version_ios.py` | Automatic iOS version management |
|
|
93
91
|
| `fastlane/` | iOS and Android Fastlane configurations |
|
|
@@ -101,8 +99,7 @@ The package installs these templates to your project:
|
|
|
101
99
|
3. Use `app-designer` to design app UI + create screenshots + design web page
|
|
102
100
|
4. Use `appstore-meta-creator` to generate metadata
|
|
103
101
|
5. Use `appstore-reviewer` to verify compliance
|
|
104
|
-
6.
|
|
105
|
-
7. Push to GitHub -- Codemagic builds and publishes automatically
|
|
102
|
+
6. Push to GitHub -- GitHub Actions builds and publishes automatically
|
|
106
103
|
|
|
107
104
|
## MCP Servers
|
|
108
105
|
|
|
@@ -114,7 +111,6 @@ The package configures these MCP servers in `.mcp.json`:
|
|
|
114
111
|
| mobile-mcp | Mobile device automation | None |
|
|
115
112
|
| stitch | AI design tool for screenshot generation | `STITCH_API_KEY` |
|
|
116
113
|
| cloudflare | Cloudflare Pages deployment | `CLOUDFLARE_API_TOKEN` + Account ID |
|
|
117
|
-
| codemagic | Codemagic CI/CD build management (27 tools) | `CODEMAGIC_API_TOKEN` |
|
|
118
114
|
|
|
119
115
|
## Non-interactive Install
|
|
120
116
|
|
|
@@ -123,13 +119,12 @@ For CI/CD environments or scripted setups, pass tokens as CLI flags to skip inte
|
|
|
123
119
|
```bash
|
|
124
120
|
npx @daemux/store-automator \
|
|
125
121
|
--bundle-id=com.company.app \
|
|
126
|
-
--codemagic-token=YOUR_CM_TOKEN \
|
|
127
122
|
--stitch-key=YOUR_STITCH_KEY \
|
|
128
123
|
--cloudflare-token=YOUR_CF_TOKEN \
|
|
129
124
|
--cloudflare-account-id=YOUR_CF_ACCOUNT_ID
|
|
130
125
|
```
|
|
131
126
|
|
|
132
|
-
Any tokens provided via flags will skip the corresponding interactive prompt. If all
|
|
127
|
+
Any tokens provided via flags will skip the corresponding interactive prompt. If all three tokens are provided, the entire interactive session is skipped. The bundle ID, if provided, is automatically written to `bundle_id` and `package_name` in `ci.config.yaml`.
|
|
133
128
|
|
|
134
129
|
## CLI Options
|
|
135
130
|
|
|
@@ -147,22 +142,9 @@ App Configuration:
|
|
|
147
142
|
--bundle-id=ID Bundle ID / Package Name (e.g., com.company.app)
|
|
148
143
|
|
|
149
144
|
MCP Token Flags (skip interactive prompts):
|
|
150
|
-
--codemagic-token=TOKEN Codemagic API token
|
|
151
145
|
--stitch-key=KEY Stitch MCP API key
|
|
152
146
|
--cloudflare-token=TOKEN Cloudflare API token
|
|
153
147
|
--cloudflare-account-id=ID Cloudflare account ID
|
|
154
|
-
|
|
155
|
-
Codemagic:
|
|
156
|
-
--codemagic-setup Register repo and optionally trigger build
|
|
157
|
-
--token=TOKEN API token (or set CM_API_TOKEN env var)
|
|
158
|
-
--branch=BRANCH Branch to build (default: main)
|
|
159
|
-
--workflow=ID Workflow ID (default: default)
|
|
160
|
-
--trigger Trigger build after setup
|
|
161
|
-
--wait Wait for build completion (implies --trigger)
|
|
162
|
-
|
|
163
|
-
GitHub Actions:
|
|
164
|
-
--github-setup Set CM_API_TOKEN secret for GitHub Actions
|
|
165
|
-
--token=TOKEN API token (or set CM_API_TOKEN env var)
|
|
166
148
|
```
|
|
167
149
|
|
|
168
150
|
## License
|
package/bin/cli.mjs
CHANGED
|
@@ -15,21 +15,10 @@ const args = process.argv.slice(2);
|
|
|
15
15
|
let scope = 'project';
|
|
16
16
|
let action = 'install';
|
|
17
17
|
let isPostinstall = false;
|
|
18
|
-
let cmTokenArg = '';
|
|
19
|
-
let cmBranch = 'main';
|
|
20
|
-
let cmWorkflowId = 'default';
|
|
21
|
-
let cmTrigger = false;
|
|
22
|
-
let cmWait = false;
|
|
23
18
|
|
|
24
19
|
const cliTokens = {};
|
|
25
20
|
|
|
26
|
-
function flagValue(arg, prefix) {
|
|
27
|
-
return arg.startsWith(prefix) ? arg.slice(prefix.length) : undefined;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
21
|
const valueFlags = {
|
|
31
|
-
'--codemagic-token=': 'codemagicToken',
|
|
32
|
-
'--codemagic-team-id=': 'codemagicTeamId',
|
|
33
22
|
'--stitch-key=': 'stitchApiKey',
|
|
34
23
|
'--cloudflare-token=': 'cloudflareToken',
|
|
35
24
|
'--cloudflare-account-id=': 'cloudflareAccountId',
|
|
@@ -39,11 +28,6 @@ const valueFlags = {
|
|
|
39
28
|
};
|
|
40
29
|
|
|
41
30
|
for (const arg of args) {
|
|
42
|
-
let v;
|
|
43
|
-
if ((v = flagValue(arg, '--token=')) !== undefined) { cmTokenArg = v; continue; }
|
|
44
|
-
if ((v = flagValue(arg, '--branch=')) !== undefined) { cmBranch = v; continue; }
|
|
45
|
-
if ((v = flagValue(arg, '--workflow=')) !== undefined) { cmWorkflowId = v; continue; }
|
|
46
|
-
|
|
47
31
|
const valueFlagEntry = Object.entries(valueFlags).find(([prefix]) => arg.startsWith(prefix));
|
|
48
32
|
if (valueFlagEntry) {
|
|
49
33
|
cliTokens[valueFlagEntry[1]] = arg.slice(valueFlagEntry[0].length);
|
|
@@ -62,21 +46,9 @@ for (const arg of args) {
|
|
|
62
46
|
case '--postinstall':
|
|
63
47
|
isPostinstall = true;
|
|
64
48
|
break;
|
|
65
|
-
case '--codemagic-setup':
|
|
66
|
-
action = 'codemagic-setup';
|
|
67
|
-
break;
|
|
68
|
-
case '--github-setup':
|
|
69
|
-
action = 'github-setup';
|
|
70
|
-
break;
|
|
71
49
|
case '--github-actions':
|
|
72
50
|
cliTokens.githubActions = true;
|
|
73
51
|
break;
|
|
74
|
-
case '--trigger':
|
|
75
|
-
cmTrigger = true;
|
|
76
|
-
break;
|
|
77
|
-
case '--wait':
|
|
78
|
-
cmWait = true;
|
|
79
|
-
break;
|
|
80
52
|
case '-h':
|
|
81
53
|
case '--help':
|
|
82
54
|
console.log(`Usage: npx @daemux/store-automator [options]
|
|
@@ -92,43 +64,26 @@ App Configuration:
|
|
|
92
64
|
--bundle-id=ID Bundle ID / Package Name (e.g., com.company.app)
|
|
93
65
|
|
|
94
66
|
MCP Token Flags (skip interactive prompts):
|
|
95
|
-
--codemagic-token=TOKEN Codemagic API token
|
|
96
|
-
--codemagic-team-id=ID Codemagic Team ID (from Teams page)
|
|
97
67
|
--stitch-key=KEY Stitch MCP API key
|
|
98
68
|
--cloudflare-token=TOKEN Cloudflare API token
|
|
99
69
|
--cloudflare-account-id=ID Cloudflare account ID
|
|
100
70
|
|
|
101
|
-
Codemagic:
|
|
102
|
-
--codemagic-setup Register repo and optionally trigger build
|
|
103
|
-
--token=TOKEN API token (or set CM_API_TOKEN env var)
|
|
104
|
-
--branch=BRANCH Branch to build (default: main)
|
|
105
|
-
--workflow=ID Workflow ID (default: default)
|
|
106
|
-
--trigger Trigger build after setup
|
|
107
|
-
--wait Wait for build completion (implies --trigger)
|
|
108
|
-
|
|
109
71
|
GitHub Actions CI mode:
|
|
110
|
-
--github-actions Use GitHub Actions
|
|
111
|
-
--match-deploy-key=PATH Path to Match deploy key file
|
|
112
|
-
--match-git-url=URL Git URL for Match certificates repo
|
|
113
|
-
|
|
114
|
-
GitHub Actions (auto-configured during install if gh CLI available):
|
|
115
|
-
--github-setup Set CM_API_TOKEN secret for GitHub Actions
|
|
116
|
-
--token=TOKEN API token (or set CM_API_TOKEN env var)
|
|
72
|
+
--github-actions Use GitHub Actions CI mode
|
|
73
|
+
--match-deploy-key=PATH Path to Match deploy key file
|
|
74
|
+
--match-git-url=URL Git URL for Match certificates repo
|
|
117
75
|
|
|
118
76
|
Examples:
|
|
119
|
-
npx @daemux/store-automator Install for project
|
|
77
|
+
npx @daemux/store-automator Install for project
|
|
120
78
|
npx @daemux/store-automator -g Install globally
|
|
121
79
|
npx @daemux/store-automator -u Uninstall from project
|
|
122
80
|
npx @daemux/store-automator -g -u Uninstall globally
|
|
123
|
-
npx @daemux/store-automator --codemagic-setup Register with Codemagic
|
|
124
|
-
npx @daemux/store-automator --codemagic-setup --trigger --wait Trigger and wait
|
|
125
|
-
npx @daemux/store-automator --github-setup Configure GitHub Actions secret
|
|
126
81
|
|
|
127
82
|
GitHub Actions install:
|
|
128
83
|
npx @daemux/store-automator --github-actions --bundle-id=ID --match-deploy-key=PATH --match-git-url=URL
|
|
129
84
|
|
|
130
|
-
Non-interactive install
|
|
131
|
-
npx @daemux/store-automator --bundle-id=ID --
|
|
85
|
+
Non-interactive install:
|
|
86
|
+
npx @daemux/store-automator --bundle-id=ID --stitch-key=KEY
|
|
132
87
|
npx @daemux/store-automator --cloudflare-token=TOKEN --cloudflare-account-id=ID`);
|
|
133
88
|
process.exit(0);
|
|
134
89
|
case '-v':
|
|
@@ -138,8 +93,6 @@ Non-interactive install (Codemagic):
|
|
|
138
93
|
}
|
|
139
94
|
}
|
|
140
95
|
|
|
141
|
-
if (cmWait) cmTrigger = true;
|
|
142
|
-
|
|
143
96
|
if (cliTokens.githubActions) {
|
|
144
97
|
const missing = [];
|
|
145
98
|
if (!cliTokens.matchDeployKey) missing.push('--match-deploy-key');
|
|
@@ -160,19 +113,7 @@ if (cliTokens.githubActions) {
|
|
|
160
113
|
notifier.notify();
|
|
161
114
|
|
|
162
115
|
try {
|
|
163
|
-
if (action === '
|
|
164
|
-
const { runCodemagicSetup } = await import('../src/codemagic-setup.mjs');
|
|
165
|
-
await runCodemagicSetup({
|
|
166
|
-
tokenArg: cmTokenArg,
|
|
167
|
-
branch: cmBranch,
|
|
168
|
-
workflowId: cmWorkflowId,
|
|
169
|
-
trigger: cmTrigger,
|
|
170
|
-
wait: cmWait,
|
|
171
|
-
});
|
|
172
|
-
} else if (action === 'github-setup') {
|
|
173
|
-
const { runGitHubSetup } = await import('../src/github-setup.mjs');
|
|
174
|
-
await runGitHubSetup({ tokenArg: cmTokenArg });
|
|
175
|
-
} else if (action === 'uninstall') {
|
|
116
|
+
if (action === 'uninstall') {
|
|
176
117
|
const { runUninstall } = await import('../src/uninstall.mjs');
|
|
177
118
|
await runUninstall(scope);
|
|
178
119
|
} else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@daemux/store-automator",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Full App Store & Google Play automation for Flutter apps with Claude Code agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -25,7 +25,6 @@
|
|
|
25
25
|
"app-store",
|
|
26
26
|
"google-play",
|
|
27
27
|
"fastlane",
|
|
28
|
-
"codemagic",
|
|
29
28
|
"ci-cd",
|
|
30
29
|
"daemux"
|
|
31
30
|
],
|
|
@@ -4,7 +4,7 @@ description: "Designs Flutter app architectures by analyzing codebase patterns,
|
|
|
4
4
|
model: opus
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
You are a senior Flutter/mobile architect who delivers actionable blueprints through deep codebase understanding and confident architectural decisions. The project targets App Store + Google Play via
|
|
7
|
+
You are a senior Flutter/mobile architect who delivers actionable blueprints through deep codebase understanding and confident architectural decisions. The project targets App Store + Google Play via GitHub Actions CI/CD.
|
|
8
8
|
|
|
9
9
|
## Core Process
|
|
10
10
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: devops
|
|
3
|
-
description: "DevOps operations:
|
|
3
|
+
description: "DevOps operations: GitHub Actions CI/CD, Firebase deployment, Cloudflare Pages deployment, Firestore management. Use PROACTIVELY for deployment, infrastructure, or CI/CD operations."
|
|
4
4
|
model: opus
|
|
5
5
|
hooks:
|
|
6
6
|
PreToolUse:
|
|
@@ -12,18 +12,18 @@ hooks:
|
|
|
12
12
|
|
|
13
13
|
**SCOPE RESTRICTION:**
|
|
14
14
|
- You CANNOT edit or create ANY local project files (no Edit/Write tools)
|
|
15
|
-
- This includes: source code, CI/CD configs, GitHub Actions workflows, scripts,
|
|
15
|
+
- This includes: source code, CI/CD configs, GitHub Actions workflows, scripts, etc.
|
|
16
16
|
- You CAN only: run deployments, check logs, monitor builds, manage infrastructure via Bash and MCP tools
|
|
17
17
|
- If ANY local file changes are needed (code, configs, CI/CD, scripts), report what needs changing and ask the developer agent to make the edits
|
|
18
18
|
|
|
19
19
|
# DevOps Agent
|
|
20
20
|
|
|
21
|
-
Handles
|
|
21
|
+
Handles GitHub Actions CI/CD, Firebase deployment, Cloudflare Pages deployment, and Firestore management for Flutter mobile apps.
|
|
22
22
|
|
|
23
23
|
## Parameters (REQUIRED)
|
|
24
24
|
|
|
25
25
|
**Mode**: One of the following
|
|
26
|
-
- `
|
|
26
|
+
- `deploy` - CI/CD build monitoring, deployment tracking, log analysis via GitHub Actions
|
|
27
27
|
- `firebase` - Deploy Cloud Functions, security rules, Firestore indexes
|
|
28
28
|
- `cloudflare` - Deploy web pages via Cloudflare Pages
|
|
29
29
|
- `database + deploy` - Deploy Firestore security rules, indexes, and run data migration scripts
|
|
@@ -33,83 +33,49 @@ Additional parameters vary by mode (see each section).
|
|
|
33
33
|
|
|
34
34
|
---
|
|
35
35
|
|
|
36
|
-
## Mode:
|
|
36
|
+
## Mode: deploy
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
Monitor and manage GitHub Actions CI/CD builds for iOS and Android. NEVER skip or abandon a failed build -- iterate until success.
|
|
39
39
|
|
|
40
40
|
### Build Pipeline
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
GitHub Actions runs two parallel workflows on push to `main`:
|
|
43
43
|
|
|
44
|
-
**iOS Release
|
|
45
|
-
**Android Release
|
|
46
|
-
|
|
47
|
-
### Token Configuration
|
|
48
|
-
|
|
49
|
-
The Codemagic API token and Team ID are auto-configured via the codemagic MCP server in `.mcp.json` (set during install). You do not need to resolve the token manually -- all MCP tool calls authenticate automatically. The `CODEMAGIC_TEAM_ID` env var enables default team resolution for team-scoped tools (`list_builds`, `get_team`, `list_team_members`, `create_variable_group`, `setup_asc_credentials`, `setup_code_signing`). If the codemagic MCP server is missing from `.mcp.json`, instruct the user to re-run `npx @daemux/store-automator` or add `--codemagic-token=TOKEN --codemagic-team-id=ID` to configure it.
|
|
44
|
+
**iOS Release** (`.github/workflows/ios-release.yml`): Upload metadata + screenshots -> Build IPA -> Code signing -> Deploy to App Store Connect -> Sync IAP
|
|
45
|
+
**Android Release** (`.github/workflows/android-release.yml`): Upload metadata + screenshots -> Check Google Play readiness -> Build AAB -> Keystore signing -> Deploy to Google Play -> Sync IAP
|
|
50
46
|
|
|
51
47
|
### Triggering Builds
|
|
52
48
|
|
|
53
|
-
|
|
49
|
+
Push to `main` branch triggers both workflows automatically:
|
|
54
50
|
```bash
|
|
55
51
|
git push origin main
|
|
56
52
|
```
|
|
57
|
-
Codemagic triggers both iOS and Android workflows automatically on push to `main`.
|
|
58
53
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
54
|
+
Or trigger manually via GitHub Actions UI or CLI:
|
|
55
|
+
```bash
|
|
56
|
+
gh workflow run ios-release.yml
|
|
57
|
+
gh workflow run android-release.yml
|
|
58
|
+
```
|
|
64
59
|
|
|
65
60
|
### Monitoring Build Status
|
|
66
61
|
|
|
67
|
-
Use
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
| Tool | Description |
|
|
74
|
-
|------|-------------|
|
|
75
|
-
| `list_apps` | List all Codemagic applications |
|
|
76
|
-
| `get_app` | Get details of a specific application |
|
|
77
|
-
| `add_app` | Add a new application to Codemagic |
|
|
78
|
-
| `start_build` | Start a new build |
|
|
79
|
-
| `get_build` | Get details of a specific build |
|
|
80
|
-
| `cancel_build` | Cancel a running build |
|
|
81
|
-
| `list_builds` | List builds for a team (V3 API, uses default team if omitted) |
|
|
82
|
-
| `get_artifact_url` | Get the download URL for a build artifact |
|
|
83
|
-
| `create_public_artifact_url` | Create a time-limited public URL for an artifact |
|
|
84
|
-
| `list_caches` | List build caches for an application |
|
|
85
|
-
| `delete_caches` | Delete build caches for an application |
|
|
86
|
-
| `setup_asc_credentials` | Create variable group with ASC credentials (uses default team if omitted) |
|
|
87
|
-
| `setup_code_signing` | Create variable group with iOS signing (uses default team if omitted) |
|
|
88
|
-
| `get_user` | Get the current authenticated user info |
|
|
89
|
-
| `list_teams` | List all teams the user belongs to |
|
|
90
|
-
| `get_team` | Get details of a specific team (uses default team if omitted) |
|
|
91
|
-
| `list_team_members` | List members of a team (uses default team if omitted) |
|
|
92
|
-
| `list_variable_groups` | List variable groups for a team or application |
|
|
93
|
-
| `get_variable_group` | Get details of a specific variable group |
|
|
94
|
-
| `create_variable_group` | Create a new variable group (uses default team if omitted) |
|
|
95
|
-
| `update_variable_group` | Update a variable group name or security setting |
|
|
96
|
-
| `delete_variable_group` | Delete a variable group |
|
|
97
|
-
| `list_variables` | List variables in a variable group |
|
|
98
|
-
| `get_variable` | Get a specific variable from a variable group |
|
|
99
|
-
| `update_variable` | Update a variable in a variable group |
|
|
100
|
-
| `delete_variable` | Delete a variable from a variable group |
|
|
101
|
-
| `bulk_import_variables` | Import multiple variables into a variable group |
|
|
62
|
+
Use GitHub CLI to monitor workflow runs:
|
|
63
|
+
```bash
|
|
64
|
+
gh run list --workflow=ios-release.yml --limit=5
|
|
65
|
+
gh run list --workflow=android-release.yml --limit=5
|
|
66
|
+
gh run watch <run-id>
|
|
67
|
+
```
|
|
102
68
|
|
|
103
69
|
### Build Failure Analysis
|
|
104
70
|
|
|
105
71
|
When a build fails:
|
|
106
|
-
1. Read the full build log
|
|
72
|
+
1. Read the full build log: `gh run view <run-id> --log-failed`
|
|
107
73
|
2. Identify the failing step (Flutter analyze, test, build, signing, upload)
|
|
108
74
|
3. Categorize the failure:
|
|
109
75
|
- **Code issue**: Flutter analyze errors, test failures -> coordinate fix with developer
|
|
110
76
|
- **Signing issue**: Certificate expired, profile mismatch -> check `creds/` and `ci.config.yaml`
|
|
111
77
|
- **Store issue**: App Store rejection, metadata error -> check `fastlane/metadata/`
|
|
112
|
-
- **Infrastructure issue**:
|
|
78
|
+
- **Infrastructure issue**: Timeout, dependency install failure -> retry or adjust config
|
|
113
79
|
4. Fix the root cause (coordinate with developer agent if code change needed)
|
|
114
80
|
5. Re-trigger the build
|
|
115
81
|
6. Repeat until both iOS and Android succeed
|
|
@@ -133,17 +99,13 @@ Versions are auto-incremented:
|
|
|
133
99
|
- Build number = latest store build number + 1
|
|
134
100
|
- Both platforms share the same version name (e.g., 1.0.0), synced from iOS
|
|
135
101
|
|
|
136
|
-
### Health Check and Log Analysis
|
|
137
|
-
|
|
138
|
-
After triggering a build, poll status every 60 seconds. Check both iOS and Android independently. If one passes and one fails, report partial success and investigate. Verify artifacts (IPA/AAB) and store submission status after success. In logs, look for `ERROR`, `FAILURE`, `EXCEPTION`, `BUILD FAILED`, check Flutter analyze, test results, code signing, and Fastlane output.
|
|
139
|
-
|
|
140
102
|
### Output Format
|
|
141
103
|
|
|
142
104
|
```
|
|
143
105
|
OPERATION: Build | Monitor | Logs | Status
|
|
144
106
|
PLATFORM: iOS | Android | Both
|
|
145
|
-
|
|
146
|
-
STATUS: queued |
|
|
107
|
+
RUN ID: [id]
|
|
108
|
+
STATUS: queued | in_progress | completed | failure
|
|
147
109
|
VERSION: [version]+[build_number]
|
|
148
110
|
RESULT: [success details or failure analysis with root cause and fix]
|
|
149
111
|
RECOMMENDATION: [next action if needed]
|
|
@@ -365,25 +327,16 @@ Analyze Firestore usage patterns and optimize queries, indexes, and security rul
|
|
|
365
327
|
|
|
366
328
|
| File | Purpose |
|
|
367
329
|
|------|---------|
|
|
368
|
-
| `ci.config.yaml` | Single source of truth for all CI/CD config
|
|
369
|
-
|
|
|
370
|
-
|
|
|
371
|
-
| `scripts/generate.sh` | Generates codemagic.yaml from ci.config.yaml |
|
|
330
|
+
| `ci.config.yaml` | Single source of truth for all CI/CD config |
|
|
331
|
+
| `.github/workflows/ios-release.yml` | GitHub Actions iOS release workflow |
|
|
332
|
+
| `.github/workflows/android-release.yml` | GitHub Actions Android release workflow |
|
|
372
333
|
| `scripts/check_changed.sh` | Detects changed files for conditional uploads |
|
|
373
334
|
| `scripts/manage_version_ios.py` | iOS version auto-increment |
|
|
374
335
|
| `scripts/check_google_play.py` | Google Play readiness checker |
|
|
375
|
-
| `.mcp.json (codemagic)` | Codemagic MCP server config and API token |
|
|
376
336
|
| `fastlane/metadata/` | Store listing metadata (iOS + Android) |
|
|
377
337
|
| `fastlane/iap_config.json` | In-app purchase configuration |
|
|
378
338
|
| `web/deploy-cloudflare.mjs` | Cloudflare Pages deployment script |
|
|
379
339
|
|
|
380
|
-
### Regenerating codemagic.yaml
|
|
381
|
-
|
|
382
|
-
After editing `ci.config.yaml`, regenerate the Codemagic config:
|
|
383
|
-
```bash
|
|
384
|
-
./scripts/generate.sh
|
|
385
|
-
```
|
|
386
|
-
|
|
387
340
|
---
|
|
388
341
|
|
|
389
342
|
## Output Footer
|
|
@@ -47,8 +47,8 @@ Track which phases are complete. All phases must pass before declaring COMPLETE:
|
|
|
47
47
|
| Phase 2: Develop | Flutter app builds (iOS + Android), tests pass, matches designs |
|
|
48
48
|
| Phase 3: Store Metadata | fastlane/metadata/ populated for all configured languages |
|
|
49
49
|
| Phase 4: Web Pages | Marketing, privacy, terms, support pages deployed; URLs working |
|
|
50
|
-
| Phase 5: CI/CD |
|
|
51
|
-
| Phase 6: First Publish | iOS submitted via
|
|
50
|
+
| Phase 5: CI/CD | GitHub Actions workflows configured, .gitignore correct, repo pushed |
|
|
51
|
+
| Phase 6: First Publish | iOS submitted via CI, Android AAB created |
|
|
52
52
|
| Phase 7: Updates | Ongoing (not required for initial COMPLETE) |
|
|
53
53
|
|
|
54
54
|
---
|
|
@@ -88,7 +88,7 @@ Before declaring COMPLETE, confirm:
|
|
|
88
88
|
- [ ] `flutter test` all passed
|
|
89
89
|
- [ ] mobile-mcp UI tests passed on iOS simulator
|
|
90
90
|
- [ ] mobile-mcp UI tests passed on Android emulator
|
|
91
|
-
- [ ]
|
|
91
|
+
- [ ] CI build status is green (coordinate with devops)
|
|
92
92
|
- [ ] Store metadata generated for ALL languages in ci.config.yaml
|
|
93
93
|
- [ ] Web pages deployed and URLs return 200 OK
|
|
94
94
|
- [ ] appstore-reviewer passed compliance checks (if applicable)
|
|
@@ -104,7 +104,7 @@ Before declaring COMPLETE, confirm:
|
|
|
104
104
|
- Either iOS or Android build fails
|
|
105
105
|
- Store metadata is missing for any configured language
|
|
106
106
|
- Web pages are not deployed or return errors
|
|
107
|
-
-
|
|
107
|
+
- CI pipeline has failures
|
|
108
108
|
- App is not published to BOTH stores (for final completion)
|
|
109
109
|
|
|
110
110
|
## UX Regression Checklist
|
|
@@ -232,7 +232,7 @@ If NOT COMPLETE -> developer fixes -> product-manager checks again (repeat until
|
|
|
232
232
|
- Android Build: PASS/FAIL
|
|
233
233
|
- UI Tests (iOS): PASS/FAIL/NOT RUN
|
|
234
234
|
- UI Tests (Android): PASS/FAIL/NOT RUN
|
|
235
|
-
-
|
|
235
|
+
- CI Pipeline: GREEN/RED/NOT CONFIGURED
|
|
236
236
|
- Store Metadata: COMPLETE/INCOMPLETE ({missing})
|
|
237
237
|
- Web Pages: DEPLOYED/NOT DEPLOYED
|
|
238
238
|
- Store Compliance: PASS/FAIL/NOT CHECKED
|
package/scripts/check_changed.sh
CHANGED
package/src/ci-config.mjs
CHANGED
|
@@ -3,8 +3,6 @@ import { join } from 'node:path';
|
|
|
3
3
|
|
|
4
4
|
const CI_CONFIG_FILE = 'ci.config.yaml';
|
|
5
5
|
const FIELD_PATTERNS = {
|
|
6
|
-
app_id: /^(\s*app_id:\s*)"[^"]*"/m,
|
|
7
|
-
team_id: /^(\s*team_id:\s*)"[^"]*"/m,
|
|
8
6
|
bundle_id: /^(\s*bundle_id:\s*)"[^"]*"/m,
|
|
9
7
|
package_name: /^(\s*package_name:\s*)"[^"]*"/m,
|
|
10
8
|
deploy_key_path: /^(\s*deploy_key_path:\s*)"[^"]*"/m,
|
|
@@ -31,14 +29,6 @@ function writeCiField(projectDir, field, value) {
|
|
|
31
29
|
}
|
|
32
30
|
}
|
|
33
31
|
|
|
34
|
-
export function writeCiAppId(projectDir, appId) {
|
|
35
|
-
return writeCiField(projectDir, 'app_id', appId);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export function writeCiTeamId(projectDir, teamId) {
|
|
39
|
-
return writeCiField(projectDir, 'team_id', teamId);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
32
|
export function writeCiBundleId(projectDir, bundleId) {
|
|
43
33
|
return writeCiField(projectDir, 'bundle_id', bundleId);
|
|
44
34
|
}
|
package/src/install-paths.mjs
CHANGED
|
@@ -1,68 +1,5 @@
|
|
|
1
|
-
import { execSync, execFileSync } from 'node:child_process';
|
|
2
1
|
import { installGitHubActionsTemplates, installMatchfile } from './templates.mjs';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
writeCiAppId, writeCiTeamId, writeMatchConfig,
|
|
6
|
-
} from './ci-config.mjs';
|
|
7
|
-
import { updateMcpAppId, updateMcpTeamId } from './mcp-setup.mjs';
|
|
8
|
-
|
|
9
|
-
function setupGitHubActionsSecret(codemagicToken) {
|
|
10
|
-
if (!codemagicToken) return false;
|
|
11
|
-
|
|
12
|
-
try {
|
|
13
|
-
execFileSync('which', ['gh'], { encoding: 'utf8', stdio: 'pipe' });
|
|
14
|
-
const authStatus = execFileSync('gh', ['auth', 'status'], { encoding: 'utf8', stdio: 'pipe' });
|
|
15
|
-
if (authStatus.includes('not logged')) return false;
|
|
16
|
-
|
|
17
|
-
execFileSync('gh', ['secret', 'set', 'CM_API_TOKEN', '--body', codemagicToken], {
|
|
18
|
-
encoding: 'utf8',
|
|
19
|
-
stdio: 'pipe',
|
|
20
|
-
});
|
|
21
|
-
return true;
|
|
22
|
-
} catch {
|
|
23
|
-
return false;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
async function setupCodemagicApp(projectDir, codemagicToken, codemagicTeamId) {
|
|
28
|
-
if (!codemagicToken) return;
|
|
29
|
-
|
|
30
|
-
let repoUrl;
|
|
31
|
-
try {
|
|
32
|
-
const raw = execSync('git remote get-url origin', {
|
|
33
|
-
encoding: 'utf8',
|
|
34
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
35
|
-
}).trim();
|
|
36
|
-
if (!raw) return;
|
|
37
|
-
repoUrl = normalizeRepoUrl(raw);
|
|
38
|
-
} catch {
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
try {
|
|
43
|
-
let app = await findAppByRepo(codemagicToken, repoUrl);
|
|
44
|
-
if (!app) {
|
|
45
|
-
app = await addApp(codemagicToken, repoUrl, codemagicTeamId);
|
|
46
|
-
console.log(`Codemagic app created: ${app.appName || app._id}`);
|
|
47
|
-
} else {
|
|
48
|
-
console.log(`Codemagic app found: ${app.appName || app._id}`);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const written = writeCiAppId(projectDir, app._id);
|
|
52
|
-
if (written) {
|
|
53
|
-
console.log(`Codemagic app_id written to ci.config.yaml`);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
updateMcpAppId(projectDir, app._id);
|
|
57
|
-
|
|
58
|
-
if (codemagicTeamId) {
|
|
59
|
-
writeCiTeamId(projectDir, codemagicTeamId);
|
|
60
|
-
updateMcpTeamId(projectDir, codemagicTeamId);
|
|
61
|
-
}
|
|
62
|
-
} catch (err) {
|
|
63
|
-
console.log(`Codemagic auto-setup skipped: ${err.message || err}`);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
2
|
+
import { writeMatchConfig } from './ci-config.mjs';
|
|
66
3
|
|
|
67
4
|
export function installGitHubActionsPath(projectDir, packageDir, cliTokens) {
|
|
68
5
|
console.log('Configuring GitHub Actions mode...');
|
|
@@ -79,14 +16,3 @@ export function installGitHubActionsPath(projectDir, packageDir, cliTokens) {
|
|
|
79
16
|
});
|
|
80
17
|
if (wrote) console.log('Match credentials written to ci.config.yaml');
|
|
81
18
|
}
|
|
82
|
-
|
|
83
|
-
export async function installCodemagicPath(projectDir, tokens) {
|
|
84
|
-
await setupCodemagicApp(projectDir, tokens.codemagicToken, tokens.codemagicTeamId);
|
|
85
|
-
|
|
86
|
-
const ghConfigured = setupGitHubActionsSecret(tokens.codemagicToken);
|
|
87
|
-
if (ghConfigured) {
|
|
88
|
-
console.log('GitHub Actions: CM_API_TOKEN secret configured.');
|
|
89
|
-
} else if (tokens.codemagicToken) {
|
|
90
|
-
console.log('GitHub Actions: secret not set (gh CLI unavailable or not authenticated).');
|
|
91
|
-
}
|
|
92
|
-
}
|