orizu 0.5.0 → 0.5.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/dist/github-setup.js +24 -2
- package/package.json +1 -1
- package/src/github-setup.ts +33 -3
package/dist/github-setup.js
CHANGED
|
@@ -54,18 +54,29 @@ export async function runGithubLink(teamSlug, io) {
|
|
|
54
54
|
const { installUrl, state } = (await start.json());
|
|
55
55
|
io.print(' Connect your team GitHub org by installing the Orizu GitHub App:');
|
|
56
56
|
io.print(` ${installUrl}`);
|
|
57
|
+
// Bug 2: personal accounts cannot host an auto-provisioned workbench.
|
|
58
|
+
io.print(' • Install into a GitHub ORGANIZATION, not a personal account. Personal');
|
|
59
|
+
io.print(' accounts are not supported for auto-provisioning; creating an org is free.');
|
|
60
|
+
// Bug 4: repo selection guidance — GitHub forces picking at least one repo.
|
|
61
|
+
io.print(' • On the "Repository access" step choose "Only select repositories" and pick');
|
|
62
|
+
io.print(' any one repo (GitHub requires at least one). Orizu adds the workbench repo');
|
|
63
|
+
io.print(' it creates automatically — do NOT choose "All repositories".');
|
|
57
64
|
if (io.openUrl) {
|
|
58
65
|
io.openUrl(installUrl);
|
|
59
|
-
io.print(' Opened the install page in your browser.
|
|
66
|
+
io.print(' Opened the install page in your browser.');
|
|
60
67
|
}
|
|
61
68
|
else {
|
|
62
|
-
io.print(' Open the URL above
|
|
69
|
+
io.print(' Open the URL above and install the App, then return here.');
|
|
63
70
|
}
|
|
71
|
+
io.print(` Waiting for you to finish installing in the browser… (Ctrl+C to abort; resume later with \`orizu github link --team ${teamSlug}\`).`);
|
|
64
72
|
const now = io.now ?? (() => Date.now());
|
|
65
73
|
const sleep = io.sleep ?? defaultSleep;
|
|
66
74
|
const interval = io.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
67
75
|
const timeout = io.pollTimeoutMs ?? DEFAULT_POLL_TIMEOUT_MS;
|
|
68
76
|
const deadline = now() + timeout;
|
|
77
|
+
// Periodic heartbeat so a long install does not look hung; never echoes state.
|
|
78
|
+
const HEARTBEAT_MS = 15000;
|
|
79
|
+
let lastHeartbeat = now();
|
|
69
80
|
for (;;) {
|
|
70
81
|
const poll = await fetcher(`/api/cli/github/link?state=${encodeURIComponent(state)}`);
|
|
71
82
|
if (poll.ok) {
|
|
@@ -77,11 +88,22 @@ export async function runGithubLink(teamSlug, io) {
|
|
|
77
88
|
if (data.status === 'pending_confirmation') {
|
|
78
89
|
return await confirmLink(teamSlug, data.orgLogin ?? null, io, fetcher);
|
|
79
90
|
}
|
|
91
|
+
// Distinguishable terminal errors (personal account / expired nonce): print
|
|
92
|
+
// the server's reason and exit non-zero instead of polling until timeout.
|
|
93
|
+
if (data.status === 'unsupported_account' || data.status === 'expired') {
|
|
94
|
+
throw new Error(data.error ??
|
|
95
|
+
`GitHub link could not be completed. Re-run \`orizu github link --team ${teamSlug}\`.`);
|
|
96
|
+
}
|
|
97
|
+
// status 'pending' → keep waiting.
|
|
80
98
|
}
|
|
81
99
|
if (now() >= deadline) {
|
|
82
100
|
throw new Error('Timed out waiting for the GitHub App install to complete. ' +
|
|
83
101
|
`Resume with \`orizu github link --team ${teamSlug}\` after finishing the install.`);
|
|
84
102
|
}
|
|
103
|
+
if (now() - lastHeartbeat >= HEARTBEAT_MS) {
|
|
104
|
+
io.print(' …still waiting for the GitHub install to complete.');
|
|
105
|
+
lastHeartbeat = now();
|
|
106
|
+
}
|
|
85
107
|
await sleep(interval);
|
|
86
108
|
}
|
|
87
109
|
}
|
package/package.json
CHANGED
package/src/github-setup.ts
CHANGED
|
@@ -86,23 +86,40 @@ export async function runGithubLink(teamSlug: string, io: GithubLinkIo): Promise
|
|
|
86
86
|
|
|
87
87
|
io.print(' Connect your team GitHub org by installing the Orizu GitHub App:')
|
|
88
88
|
io.print(` ${installUrl}`)
|
|
89
|
+
// Bug 2: personal accounts cannot host an auto-provisioned workbench.
|
|
90
|
+
io.print(' • Install into a GitHub ORGANIZATION, not a personal account. Personal')
|
|
91
|
+
io.print(' accounts are not supported for auto-provisioning; creating an org is free.')
|
|
92
|
+
// Bug 4: repo selection guidance — GitHub forces picking at least one repo.
|
|
93
|
+
io.print(' • On the "Repository access" step choose "Only select repositories" and pick')
|
|
94
|
+
io.print(' any one repo (GitHub requires at least one). Orizu adds the workbench repo')
|
|
95
|
+
io.print(' it creates automatically — do NOT choose "All repositories".')
|
|
89
96
|
if (io.openUrl) {
|
|
90
97
|
io.openUrl(installUrl)
|
|
91
|
-
io.print(' Opened the install page in your browser.
|
|
98
|
+
io.print(' Opened the install page in your browser.')
|
|
92
99
|
} else {
|
|
93
|
-
io.print(' Open the URL above
|
|
100
|
+
io.print(' Open the URL above and install the App, then return here.')
|
|
94
101
|
}
|
|
102
|
+
io.print(
|
|
103
|
+
` Waiting for you to finish installing in the browser… (Ctrl+C to abort; resume later with \`orizu github link --team ${teamSlug}\`).`
|
|
104
|
+
)
|
|
95
105
|
|
|
96
106
|
const now = io.now ?? (() => Date.now())
|
|
97
107
|
const sleep = io.sleep ?? defaultSleep
|
|
98
108
|
const interval = io.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS
|
|
99
109
|
const timeout = io.pollTimeoutMs ?? DEFAULT_POLL_TIMEOUT_MS
|
|
100
110
|
const deadline = now() + timeout
|
|
111
|
+
// Periodic heartbeat so a long install does not look hung; never echoes state.
|
|
112
|
+
const HEARTBEAT_MS = 15000
|
|
113
|
+
let lastHeartbeat = now()
|
|
101
114
|
|
|
102
115
|
for (;;) {
|
|
103
116
|
const poll = await fetcher(`/api/cli/github/link?state=${encodeURIComponent(state)}`)
|
|
104
117
|
if (poll.ok) {
|
|
105
|
-
const data = (await poll.json()) as {
|
|
118
|
+
const data = (await poll.json()) as {
|
|
119
|
+
status: string
|
|
120
|
+
orgLogin?: string | null
|
|
121
|
+
error?: string
|
|
122
|
+
}
|
|
106
123
|
if (data.status === 'active') {
|
|
107
124
|
io.print(` GitHub org connected${data.orgLogin ? ` (${data.orgLogin})` : ''}.`)
|
|
108
125
|
return { status: 'active', orgLogin: data.orgLogin ?? null, alreadyLinked: false }
|
|
@@ -110,6 +127,15 @@ export async function runGithubLink(teamSlug: string, io: GithubLinkIo): Promise
|
|
|
110
127
|
if (data.status === 'pending_confirmation') {
|
|
111
128
|
return await confirmLink(teamSlug, data.orgLogin ?? null, io, fetcher)
|
|
112
129
|
}
|
|
130
|
+
// Distinguishable terminal errors (personal account / expired nonce): print
|
|
131
|
+
// the server's reason and exit non-zero instead of polling until timeout.
|
|
132
|
+
if (data.status === 'unsupported_account' || data.status === 'expired') {
|
|
133
|
+
throw new Error(
|
|
134
|
+
data.error ??
|
|
135
|
+
`GitHub link could not be completed. Re-run \`orizu github link --team ${teamSlug}\`.`
|
|
136
|
+
)
|
|
137
|
+
}
|
|
138
|
+
// status 'pending' → keep waiting.
|
|
113
139
|
}
|
|
114
140
|
if (now() >= deadline) {
|
|
115
141
|
throw new Error(
|
|
@@ -117,6 +143,10 @@ export async function runGithubLink(teamSlug: string, io: GithubLinkIo): Promise
|
|
|
117
143
|
`Resume with \`orizu github link --team ${teamSlug}\` after finishing the install.`
|
|
118
144
|
)
|
|
119
145
|
}
|
|
146
|
+
if (now() - lastHeartbeat >= HEARTBEAT_MS) {
|
|
147
|
+
io.print(' …still waiting for the GitHub install to complete.')
|
|
148
|
+
lastHeartbeat = now()
|
|
149
|
+
}
|
|
120
150
|
await sleep(interval)
|
|
121
151
|
}
|
|
122
152
|
}
|