arcadible 0.1.37 → 0.1.38
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/bin/arc-deploy.js +18 -40
- package/package.json +1 -1
- package/src/action/deploy/wait.js +13 -8
- package/src/action/predeploy/git.js +43 -0
- package/src/action/predeploy/tool-git.js +25 -24
- package/src/api.js +23 -12
- package/src/cli/predeploy.js +1 -1
- package/src/phrase.js +14 -21
package/bin/arc-deploy.js
CHANGED
|
@@ -109,10 +109,10 @@ const handler = function ({ json, pb, quiet, sw }) {
|
|
|
109
109
|
|
|
110
110
|
// what was deployed, whether workflow.build ran, where it will be once it's
|
|
111
111
|
// published (the store only shows production), and what happens next. Once
|
|
112
|
-
// waited on, it's published, so it says so.
|
|
112
|
+
// waited on, it's published, so it says so.
|
|
113
113
|
const report = function (
|
|
114
114
|
{ built, channel, store, tag, url, version },
|
|
115
|
-
{ git,
|
|
115
|
+
{ git, published },
|
|
116
116
|
) {
|
|
117
117
|
let heading = git
|
|
118
118
|
? phrase.tagPushed(tag)
|
|
@@ -124,36 +124,19 @@ const report = function (
|
|
|
124
124
|
heading = phrase.releasePublished(version.to, channel, built);
|
|
125
125
|
next = null;
|
|
126
126
|
}
|
|
127
|
-
log.result(heading, [
|
|
128
|
-
store ? ["Store:", store] : null,
|
|
129
|
-
["Play:", url],
|
|
130
|
-
next,
|
|
131
|
-
note ?? null,
|
|
132
|
-
]);
|
|
127
|
+
log.result(heading, [store ? ["Store:", store] : null, ["Play:", url], next]);
|
|
133
128
|
};
|
|
134
129
|
|
|
135
130
|
// [function]
|
|
136
131
|
|
|
137
132
|
// the account, or null when there's none or it can't be refreshed: for a git
|
|
138
|
-
// deploy, which
|
|
133
|
+
// deploy, which needs none.
|
|
139
134
|
const whoamiIfAny = function (opts) {
|
|
140
135
|
return whoami(opts).catch(() => null);
|
|
141
136
|
};
|
|
142
137
|
|
|
143
138
|
// [function]
|
|
144
139
|
|
|
145
|
-
// whether `current` can wait for a git release: only the game's owner can see
|
|
146
|
-
// its releases. A token's account isn't known, so it waits, and so does any
|
|
147
|
-
// account when the owner couldn't be looked up.
|
|
148
|
-
const canWait = function (current, owner) {
|
|
149
|
-
if (!current) {
|
|
150
|
-
return false;
|
|
151
|
-
}
|
|
152
|
-
return Boolean(current.token) || owner === null || owner === current.user?.id;
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
// [function]
|
|
156
|
-
|
|
157
140
|
// the release, as `--json` prints it.
|
|
158
141
|
const releaseJson = function (row) {
|
|
159
142
|
if (!row) {
|
|
@@ -178,7 +161,7 @@ const waitAndReport = async function (
|
|
|
178
161
|
current,
|
|
179
162
|
deployed,
|
|
180
163
|
result,
|
|
181
|
-
{ git, json, quiet, root, since, timeout },
|
|
164
|
+
{ git, json, owner, quiet, root, since, timeout },
|
|
182
165
|
) {
|
|
183
166
|
let sw = new SpinnerWheel(phrase.releaseWaiting(git));
|
|
184
167
|
sw.start(json || quiet);
|
|
@@ -188,7 +171,7 @@ const waitAndReport = async function (
|
|
|
188
171
|
waited = await wait(
|
|
189
172
|
current,
|
|
190
173
|
deployed,
|
|
191
|
-
{ git, root, since, timeout },
|
|
174
|
+
{ git, owner, root, since, timeout },
|
|
192
175
|
{
|
|
193
176
|
onRelease() {
|
|
194
177
|
// found: GitHub Actions is done, and Arcadible publishes it now.
|
|
@@ -263,8 +246,9 @@ const start = function (argv) {
|
|
|
263
246
|
const timeout = Number(argv.timeout ?? TIMEOUT[git ? "git" : "direct"]);
|
|
264
247
|
const root = resolve(process.cwd(), argv.cwd);
|
|
265
248
|
let pb = null;
|
|
266
|
-
// the
|
|
267
|
-
|
|
249
|
+
// the game's account, when Arcadible could say: a git deploy's owner waits
|
|
250
|
+
// among their own releases.
|
|
251
|
+
let owner = null;
|
|
268
252
|
// the project, parsed once and given to each step. A build can write files
|
|
269
253
|
// the manifest reads, such as art, so it's parsed again after one runs.
|
|
270
254
|
let parsed = null;
|
|
@@ -288,10 +272,9 @@ const start = function (argv) {
|
|
|
288
272
|
sw.stop(true);
|
|
289
273
|
sw = new SpinnerWheel("Checking... %s");
|
|
290
274
|
// git deploys need no login: anyone who can push to the repository can
|
|
291
|
-
// release, and the Arcadible GitHub App publishes the release.
|
|
292
|
-
//
|
|
293
|
-
//
|
|
294
|
-
// so a git deploy that isn't logged in neither checks nor waits.
|
|
275
|
+
// release, and the Arcadible GitHub App publishes the release. Anyone
|
|
276
|
+
// can wait for it too; the game's owner, logged in, waits among their
|
|
277
|
+
// own releases, which also say when the repository isn't connected.
|
|
295
278
|
if (git) {
|
|
296
279
|
return whoamiIfAny({ handler: handler({ json, pb, quiet, sw }) });
|
|
297
280
|
}
|
|
@@ -318,15 +301,12 @@ const start = function (argv) {
|
|
|
318
301
|
})
|
|
319
302
|
.then(([current, predeployed]) => {
|
|
320
303
|
sw.stop(true);
|
|
321
|
-
|
|
322
|
-
if (current && !waits) {
|
|
323
|
-
notWaited = phrase.releaseNotWaitedOwner();
|
|
324
|
-
}
|
|
304
|
+
owner = predeployed.owner ?? null;
|
|
325
305
|
sw = new SpinnerWheel("Building... %s");
|
|
326
306
|
sw.start(git || json || quiet);
|
|
327
307
|
return Promise.all([
|
|
328
|
-
// whoami
|
|
329
|
-
|
|
308
|
+
// whoami
|
|
309
|
+
current,
|
|
330
310
|
// build
|
|
331
311
|
git ? null : build({ project: parsed, root }),
|
|
332
312
|
]);
|
|
@@ -380,10 +360,11 @@ const start = function (argv) {
|
|
|
380
360
|
delete shown.release;
|
|
381
361
|
const result = git ? shown : { built, ...shown };
|
|
382
362
|
sw.stop(true);
|
|
383
|
-
if (argv.wait
|
|
363
|
+
if (argv.wait) {
|
|
384
364
|
return waitAndReport(current, deployed, result, {
|
|
385
365
|
git,
|
|
386
366
|
json,
|
|
367
|
+
owner,
|
|
387
368
|
quiet,
|
|
388
369
|
root,
|
|
389
370
|
since,
|
|
@@ -393,10 +374,7 @@ const start = function (argv) {
|
|
|
393
374
|
if (json) {
|
|
394
375
|
print(result);
|
|
395
376
|
} else if (!quiet) {
|
|
396
|
-
report(result, {
|
|
397
|
-
git,
|
|
398
|
-
note: argv.wait ? notWaited : null,
|
|
399
|
-
});
|
|
377
|
+
report(result, { git });
|
|
400
378
|
}
|
|
401
379
|
return null;
|
|
402
380
|
})
|
package/package.json
CHANGED
|
@@ -67,15 +67,16 @@ const findDirect = function (id, headers) {
|
|
|
67
67
|
// [function]
|
|
68
68
|
|
|
69
69
|
// a git deploy's release: GitHub's, for this version, made since the tag was
|
|
70
|
-
// pushed. Null until GitHub Actions has built it.
|
|
71
|
-
// account's releases, which include one with no game: a
|
|
72
|
-
// isn't connected fails that way (repo_not_connected).
|
|
73
|
-
//
|
|
70
|
+
// pushed. Null until GitHub Actions has built it. The game's owner looks
|
|
71
|
+
// among their account's releases, which include one with no game: a
|
|
72
|
+
// repository that isn't connected fails that way (repo_not_connected).
|
|
73
|
+
// anyone else, logged in or not, looks among the game's, which anyone can
|
|
74
|
+
// read.
|
|
74
75
|
const findGit = function ({ account, game, headers, since, version }) {
|
|
75
76
|
const newest = account
|
|
76
77
|
? () => api.accountReleases(account, { limit: 20, select: SELECT }, headers)
|
|
77
78
|
: () =>
|
|
78
|
-
api.
|
|
79
|
+
api.discoverGameReleases(game, { limit: 10, select: SELECT, version });
|
|
79
80
|
return () =>
|
|
80
81
|
newest().then(
|
|
81
82
|
(rows) =>
|
|
@@ -127,17 +128,21 @@ const poll = function (find, timeout, onRelease) {
|
|
|
127
128
|
|
|
128
129
|
// waits on a deploy's release. `deployed` is what the deploy resolved: a
|
|
129
130
|
// direct deploy's has the release's id, and a git deploy's its game.
|
|
131
|
+
// `owner` is the game's account, when it's known: only they get Studio's
|
|
132
|
+
// link, since only they can open it. A token's account isn't known.
|
|
130
133
|
const main = function (
|
|
131
134
|
current,
|
|
132
135
|
deployed,
|
|
133
|
-
{ git: isGit, root, since, timeout },
|
|
136
|
+
{ git: isGit, owner, root, since, timeout },
|
|
134
137
|
{ onRelease } = {},
|
|
135
138
|
) {
|
|
136
139
|
const headers = api.auth(current?.session?.access_token);
|
|
137
140
|
const game = deployed.game;
|
|
141
|
+
const account = current?.token ? null : (current?.user?.id ?? null);
|
|
142
|
+
const owns = !isGit || (account !== null && account === owner);
|
|
138
143
|
const find = isGit
|
|
139
144
|
? findGit({
|
|
140
|
-
account:
|
|
145
|
+
account: owns ? account : null,
|
|
141
146
|
game,
|
|
142
147
|
headers,
|
|
143
148
|
since,
|
|
@@ -150,7 +155,7 @@ const main = function (
|
|
|
150
155
|
]).then(([{ release, timedOut }, actions]) => ({
|
|
151
156
|
actions,
|
|
152
157
|
release,
|
|
153
|
-
studio: studioUrl(game),
|
|
158
|
+
studio: owns ? studioUrl(game) : null,
|
|
154
159
|
timedOut,
|
|
155
160
|
}));
|
|
156
161
|
};
|
|
@@ -22,6 +22,13 @@ const HANDLE = cfgproduct.handle;
|
|
|
22
22
|
const PREFIX = `${HANDLE}/release/v`;
|
|
23
23
|
// the release workflow, which builds the release on GitHub Actions.
|
|
24
24
|
const WORKFLOW = ".github/workflows/arcadible-release.yml";
|
|
25
|
+
// a remote's URL: `scheme://[user@]host/path`, or scp-like
|
|
26
|
+
// `[user@]host:path`. A path on this machine is neither.
|
|
27
|
+
const URL_REMOTE = /^[a-z][a-z0-9+.-]*:\/\/(?:[^@/\s]+@)?[^/\s]+\/(\S+)$/iu;
|
|
28
|
+
const URL_SCP = /^(?:[^@/\s]+@)?[^:/\s]{2,}:(?!\/)(\S+)$/u;
|
|
29
|
+
// the names GitHub allows: an account's, and a repository's.
|
|
30
|
+
const NAME_OWNER = /^[A-Za-z0-9-]{1,39}$/u;
|
|
31
|
+
const NAME_REPO = /^[A-Za-z0-9._-]{1,100}$/u;
|
|
25
32
|
|
|
26
33
|
// [function]
|
|
27
34
|
|
|
@@ -99,6 +106,40 @@ const ensureWorkflow = function (root) {
|
|
|
99
106
|
|
|
100
107
|
// [function]
|
|
101
108
|
|
|
109
|
+
// a remote URL's repository, as { owner, name }: the last two parts of its
|
|
110
|
+
// path. The host isn't checked, so an SSH alias for GitHub works too. Null
|
|
111
|
+
// for a path on this machine, or one that isn't owner/name.
|
|
112
|
+
const repoOf = function (url) {
|
|
113
|
+
const path = URL_REMOTE.exec(url)?.[1] ?? URL_SCP.exec(url)?.[1] ?? null;
|
|
114
|
+
if (!path) {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
const parts = path
|
|
118
|
+
.replace(/\/+$/u, "")
|
|
119
|
+
.replace(/\.git$/u, "")
|
|
120
|
+
.split("/");
|
|
121
|
+
if (parts.length < 2) {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
const [owner, name] = parts.slice(-2);
|
|
125
|
+
return NAME_OWNER.test(owner) && NAME_REPO.test(name)
|
|
126
|
+
? { name, owner }
|
|
127
|
+
: null;
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
// [function]
|
|
131
|
+
|
|
132
|
+
// origin's repository, from its URL as configured (before any `insteadOf`),
|
|
133
|
+
// or null when it has none, or it isn't a repository on a host.
|
|
134
|
+
const originRepo = function (root) {
|
|
135
|
+
return git(root, ["config", "--get", "remote.origin.url"]).then(
|
|
136
|
+
(stdout) => repoOf(stdout.trim()),
|
|
137
|
+
() => null,
|
|
138
|
+
);
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
// [function]
|
|
142
|
+
|
|
102
143
|
const hasTagLocal = function (root, tag) {
|
|
103
144
|
return git(root, ["tag", "--list", tag]).then((stdout) =>
|
|
104
145
|
Boolean(stdout.trim()),
|
|
@@ -141,5 +182,7 @@ module.exports = {
|
|
|
141
182
|
ensureWorkflow,
|
|
142
183
|
failWith,
|
|
143
184
|
git,
|
|
185
|
+
originRepo,
|
|
186
|
+
repoOf,
|
|
144
187
|
tagOf,
|
|
145
188
|
};
|
|
@@ -21,6 +21,7 @@ const ensureRemote = git.ensureRemote;
|
|
|
21
21
|
const ensureRepo = git.ensureRepo;
|
|
22
22
|
const ensureTagFree = git.ensureTagFree;
|
|
23
23
|
const ensureWorkflow = git.ensureWorkflow;
|
|
24
|
+
const originRepo = git.originRepo;
|
|
24
25
|
|
|
25
26
|
// [function]
|
|
26
27
|
|
|
@@ -81,55 +82,55 @@ const ensureProject = function (root) {
|
|
|
81
82
|
|
|
82
83
|
// [function]
|
|
83
84
|
|
|
84
|
-
// fails when the game
|
|
85
|
-
// refuse (repo_not_connected)
|
|
86
|
-
//
|
|
87
|
-
//
|
|
88
|
-
const ensureConnected = function (
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
85
|
+
// fails when origin isn't the game's connected repository, which Arcadible
|
|
86
|
+
// would refuse (repo_not_connected) once GitHub Actions had built it. It's
|
|
87
|
+
// asked by name, which needs no login, so it checks whoever pushes. Skipped
|
|
88
|
+
// when origin is a path on this machine, or Arcadible can't be reached.
|
|
89
|
+
const ensureConnected = function (root, { handle, id }) {
|
|
90
|
+
let repo = null;
|
|
91
|
+
return originRepo(root)
|
|
92
|
+
.then((found) => {
|
|
93
|
+
repo = found;
|
|
94
|
+
return repo
|
|
95
|
+
? lookup(api.discoverGameRepo(id, repo.owner, repo.name))
|
|
96
|
+
: null;
|
|
97
|
+
})
|
|
98
|
+
.then((connected) => {
|
|
99
|
+
if (connected?.status === 404) {
|
|
96
100
|
throw new ArcError(
|
|
97
101
|
cfgcode.REPO_NOT_CONNECTED,
|
|
98
102
|
phrase.gameRepoMissing(
|
|
99
103
|
handle ?? id,
|
|
104
|
+
`${repo.owner}/${repo.name}`,
|
|
100
105
|
`${cfguri.HOST_HTTP_STUDIO}/games/${id}/repository`,
|
|
101
106
|
),
|
|
102
107
|
);
|
|
103
108
|
}
|
|
104
|
-
}
|
|
105
|
-
() => null,
|
|
106
|
-
);
|
|
109
|
+
});
|
|
107
110
|
};
|
|
108
111
|
|
|
109
112
|
// [function]
|
|
110
113
|
|
|
111
|
-
// the release's checks: its tag is free, Arcadible would publish it, and
|
|
112
|
-
//
|
|
113
|
-
//
|
|
114
|
-
const ensureRelease = function (root,
|
|
114
|
+
// the release's checks: its tag is free, Arcadible would publish it, and
|
|
115
|
+
// origin is its connected repository. resolves with the version, and the
|
|
116
|
+
// game's owner, who waits on the release among their own.
|
|
117
|
+
const ensureRelease = function (root, game, handler) {
|
|
115
118
|
return ensureTagFree(root, game.version)
|
|
116
119
|
.then(() => ensurePublishable(game, handler))
|
|
117
|
-
.then((owner) =>
|
|
118
|
-
Promise.all([owner, ensureConnected(current, game, owner)]),
|
|
119
|
-
)
|
|
120
|
+
.then((owner) => Promise.all([owner, ensureConnected(root, game)]))
|
|
120
121
|
.then(([owner]) => ({ owner, to: game.version }));
|
|
121
122
|
};
|
|
122
123
|
|
|
123
124
|
// [function]
|
|
124
125
|
|
|
125
|
-
const main = function (
|
|
126
|
+
const main = function (conf, { onPredeployBegin, ...handler }) {
|
|
126
127
|
const root = conf.root;
|
|
127
128
|
if (onPredeployBegin) {
|
|
128
129
|
onPredeployBegin();
|
|
129
130
|
}
|
|
130
131
|
return given(conf)
|
|
131
132
|
.then(({ game }) => Promise.all([game, ensureProject(root)]))
|
|
132
|
-
.then(([game]) => ensureRelease(root,
|
|
133
|
+
.then(([game]) => ensureRelease(root, game, handler));
|
|
133
134
|
};
|
|
134
135
|
|
|
135
136
|
// [export]
|
package/src/api.js
CHANGED
|
@@ -77,35 +77,46 @@ const discoverGameBuild = function (id, version, params, headers) {
|
|
|
77
77
|
|
|
78
78
|
// [function]
|
|
79
79
|
|
|
80
|
-
|
|
80
|
+
// a game's releases, which anyone can read: what each says about itself.
|
|
81
|
+
const discoverGameReleases = function (id, params, headers) {
|
|
81
82
|
return request.get(
|
|
82
|
-
endpoint(`/games/${id}/
|
|
83
|
+
endpoint(`/discover/games/${id}/releases`, params),
|
|
83
84
|
headers,
|
|
84
85
|
);
|
|
85
86
|
};
|
|
86
87
|
|
|
87
88
|
// [function]
|
|
88
89
|
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
// the game's connected repository, if it's `owner/name`; otherwise 404.
|
|
91
|
+
const discoverGameRepo = function (id, owner, name, params, headers) {
|
|
92
|
+
return request.get(
|
|
93
|
+
endpoint(
|
|
94
|
+
`/discover/games/${id}/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}`,
|
|
95
|
+
params,
|
|
96
|
+
),
|
|
97
|
+
headers,
|
|
98
|
+
);
|
|
91
99
|
};
|
|
92
100
|
|
|
93
101
|
// [function]
|
|
94
102
|
|
|
95
|
-
const
|
|
96
|
-
return request.get(
|
|
103
|
+
const gameBuild = function (id, version, params, headers) {
|
|
104
|
+
return request.get(
|
|
105
|
+
endpoint(`/games/${id}/builds/${version}`, params),
|
|
106
|
+
headers,
|
|
107
|
+
);
|
|
97
108
|
};
|
|
98
109
|
|
|
99
110
|
// [function]
|
|
100
111
|
|
|
101
|
-
const
|
|
102
|
-
return request.get(endpoint(`/
|
|
112
|
+
const release = function (id, params, headers) {
|
|
113
|
+
return request.get(endpoint(`/releases/${id}`, params), headers);
|
|
103
114
|
};
|
|
104
115
|
|
|
105
116
|
// [function]
|
|
106
117
|
|
|
107
|
-
const
|
|
108
|
-
return request.get(endpoint(`/
|
|
118
|
+
const accountReleases = function (id, params, headers) {
|
|
119
|
+
return request.get(endpoint(`/accounts/${id}/releases`, params), headers);
|
|
109
120
|
};
|
|
110
121
|
|
|
111
122
|
// [export]
|
|
@@ -116,10 +127,10 @@ module.exports = {
|
|
|
116
127
|
discoverGame,
|
|
117
128
|
discoverGameBuild,
|
|
118
129
|
discoverGameBuilds,
|
|
130
|
+
discoverGameReleases,
|
|
131
|
+
discoverGameRepo,
|
|
119
132
|
flow,
|
|
120
133
|
gameBuild,
|
|
121
|
-
gameReleases,
|
|
122
|
-
gameRepos,
|
|
123
134
|
postAuthRefresh,
|
|
124
135
|
postFlow,
|
|
125
136
|
postUpload,
|
package/src/cli/predeploy.js
CHANGED
|
@@ -9,7 +9,7 @@ const predeployToolGit = require("../action/predeploy/tool-git");
|
|
|
9
9
|
|
|
10
10
|
const main = function ({ current, git, handler, ...conf }) {
|
|
11
11
|
return git
|
|
12
|
-
? predeployToolGit(
|
|
12
|
+
? predeployToolGit(conf, handler)
|
|
13
13
|
: predeployTool(current, conf, handler);
|
|
14
14
|
};
|
|
15
15
|
|
package/src/phrase.js
CHANGED
|
@@ -171,9 +171,10 @@ const gameNotDeployed = function (game) {
|
|
|
171
171
|
|
|
172
172
|
// [function]
|
|
173
173
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
174
|
+
// origin isn't the game's connected repository: none is, or another is.
|
|
175
|
+
const gameRepoMissing = function (game, repo, url) {
|
|
176
|
+
return blocks(`${repo} isn't ${game}'s repository on ${TITLE}.`, [
|
|
177
|
+
`The game's owner connects it in ${TITLE} Studio, on the game's Repository tab, and connects it again if it was renamed on GitHub:`,
|
|
177
178
|
url,
|
|
178
179
|
]);
|
|
179
180
|
};
|
|
@@ -435,30 +436,18 @@ const packageUncompressedTooLarge = function (size) {
|
|
|
435
436
|
|
|
436
437
|
// a failed release's message, a sentence to a line, then its reason code
|
|
437
438
|
// and where to see it.
|
|
439
|
+
// `studio` is the game's builds in Studio, for its owner; anyone else can't
|
|
440
|
+
// open it.
|
|
438
441
|
const releaseFailed = function ({ message, reason }, studio) {
|
|
439
442
|
return blocks(
|
|
440
443
|
(message ?? "").split(/(?<=\.)\s+/u).join("\n"),
|
|
441
444
|
`Reason: ${reason}.`,
|
|
442
|
-
[`${TITLE} Studio:`, studio],
|
|
445
|
+
...(studio ? [[`${TITLE} Studio:`, studio]] : []),
|
|
443
446
|
);
|
|
444
447
|
};
|
|
445
448
|
|
|
446
449
|
// [function]
|
|
447
450
|
|
|
448
|
-
// a git deploy that isn't logged in can't read its release, so it doesn't
|
|
449
|
-
// wait for it.
|
|
450
|
-
const releaseNotWaited = function () {
|
|
451
|
-
return `Log in to wait for it: ${cmdLogin()}.`;
|
|
452
|
-
};
|
|
453
|
-
|
|
454
|
-
// [function]
|
|
455
|
-
|
|
456
|
-
const releaseNotWaitedOwner = function () {
|
|
457
|
-
return "Only the game's owner can wait for its release.";
|
|
458
|
-
};
|
|
459
|
-
|
|
460
|
-
// [function]
|
|
461
|
-
|
|
462
451
|
// `built` when workflow.build ran first.
|
|
463
452
|
const releasePublished = function (version, channel, built) {
|
|
464
453
|
return `${built ? "Built and published" : "Published"} v${version} to ${channel}.`;
|
|
@@ -475,12 +464,18 @@ const releaseTimedOut = function (
|
|
|
475
464
|
{ actions, found, git, studio },
|
|
476
465
|
) {
|
|
477
466
|
const head = `Waited ${waited(seconds)} for v${version}.`;
|
|
478
|
-
if (found || !git) {
|
|
467
|
+
if ((found || !git) && studio) {
|
|
479
468
|
return blocks(head, [
|
|
480
469
|
`It may still finish. See it in ${TITLE} Studio:`,
|
|
481
470
|
studio,
|
|
482
471
|
]);
|
|
483
472
|
}
|
|
473
|
+
if (found) {
|
|
474
|
+
return blocks(
|
|
475
|
+
head,
|
|
476
|
+
`It may still finish. The ${TITLE} check on the tagged commit says how it went.`,
|
|
477
|
+
);
|
|
478
|
+
}
|
|
484
479
|
return blocks(
|
|
485
480
|
head,
|
|
486
481
|
[
|
|
@@ -789,8 +784,6 @@ module.exports = {
|
|
|
789
784
|
packageTooManyFiles,
|
|
790
785
|
packageUncompressedTooLarge,
|
|
791
786
|
releaseFailed,
|
|
792
|
-
releaseNotWaited,
|
|
793
|
-
releaseNotWaitedOwner,
|
|
794
787
|
releasePublished,
|
|
795
788
|
releaseTimedOut,
|
|
796
789
|
releaseWaiting,
|