@studiometa/forge-cli 0.5.4 → 0.5.6
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/README.md +1 -1
- package/dist/cli.js +28 -9
- package/dist/cli.js.map +1 -1
- package/dist/commands/sites/apply/apply.d.ts +1 -1
- package/dist/commands/sites/apply/apply.d.ts.map +1 -1
- package/dist/commands/sites/apply/test-fixtures.d.ts +4 -0
- package/dist/commands/sites/apply/test-fixtures.d.ts.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -218,7 +218,7 @@ A worker or a scheduled job matches the file when its command, directory, proces
|
|
|
218
218
|
- Without the `workers` key, no worker is read or deleted. With `"workers": []`, all the workers of the site are deleted. The same applies to `schedule`.
|
|
219
219
|
- The site, its aliases, its database and its `.env` keys are never deleted.
|
|
220
220
|
|
|
221
|
-
`loadBalancer` sends the traffic of the load balancer to the server of the file. The site of the load balancer is the one named `domain` or one of the `aliases`. When no site matches, `--check` and `apply` exit `3` before any change. When two sites match, they exit `3` too. The Forge API cannot create a site on a load balancer: create it in Forge (New site on the load balancer), with its certificate. To move a site to another server, change `server`: `apply`
|
|
221
|
+
`loadBalancer` sends the traffic of the load balancer to the server of the file. The site of the load balancer is the one named `domain` or one of the `aliases`. When no site matches, `--check` and `apply` exit `3` before any change. When two sites match, they exit `3` too. The Forge API cannot create a site on a load balancer: create it in Forge (New site on the load balancer), with its certificate. The DNS points to the load balancer, so a change of node needs no DNS change. To move a site to another server, do not only change `server`: `apply` would send the traffic to the new site at once, before its first deployment and without its data. Declare the new server in a second site file without `loadBalancer`, deploy and test it, then move `loadBalancer` to that file. Only one site file declares `loadBalancer` for a site: with the key in two files, each `apply` replaces the node of the other.
|
|
222
222
|
|
|
223
223
|
With `--check`, `apply` prints the plan and changes nothing. It exits `0` when Forge matches the file, `1` when it differs, and another code on an error (`3` for an invalid file). Every deletion shows its ID and full command. The plan gives `.env` key names only, never values, and shows a generated password as `<generated>`. With `--format json`, it prints `{ "inSync": false, "changes": [...], "warnings": [...] }`.
|
|
224
224
|
|
package/dist/cli.js
CHANGED
|
@@ -5365,20 +5365,27 @@ var REPOSITORY_HINT = (serverId) => `Check that the git host accepts the key of
|
|
|
5365
5365
|
var defaultSleep = (ms) => new Promise((resolve) => {
|
|
5366
5366
|
setTimeout(resolve, ms);
|
|
5367
5367
|
});
|
|
5368
|
-
|
|
5368
|
+
/**
|
|
5369
|
+
* Read a new resource until Forge has installed it. Throw the error of `fail` when its status is
|
|
5370
|
+
* `failed` or when it is not installed in time.
|
|
5371
|
+
*/
|
|
5372
|
+
async function waitForInstalled(read, fail, options) {
|
|
5369
5373
|
const sleep = options.sleep ?? defaultSleep;
|
|
5370
5374
|
const interval = options.pollIntervalMs ?? 5e3;
|
|
5371
5375
|
const timeout = options.timeoutMs ?? 6e5;
|
|
5372
5376
|
for (let waited = 0;; waited += interval) {
|
|
5373
|
-
const
|
|
5374
|
-
|
|
5375
|
-
|
|
5376
|
-
}, ctx)).data;
|
|
5377
|
-
if (site.status === "installed") return;
|
|
5378
|
-
if (waited >= timeout) throw new ApplyError(`Site ${site.name} is still ${site.status} on Forge`, ["Run forge sites apply again once the site is installed", ...file.repository ? [REPOSITORY_HINT(serverId)] : []]);
|
|
5377
|
+
const resource = await read();
|
|
5378
|
+
if (resource.status === "installed") return;
|
|
5379
|
+
if (resource.status === "failed" || waited >= timeout) throw fail(resource);
|
|
5379
5380
|
await sleep(interval);
|
|
5380
5381
|
}
|
|
5381
5382
|
}
|
|
5383
|
+
async function waitForSite(file, serverId, siteId, ctx, options) {
|
|
5384
|
+
await waitForInstalled(async () => (await getSite({
|
|
5385
|
+
server_id: serverId,
|
|
5386
|
+
site_id: siteId
|
|
5387
|
+
}, ctx)).data, (site) => new ApplyError(`Site ${site.name} is still ${site.status} on Forge`, ["Run forge sites apply again once the site is installed", ...file.repository ? [REPOSITORY_HINT(serverId)] : []]), options);
|
|
5388
|
+
}
|
|
5382
5389
|
/**
|
|
5383
5390
|
* Create the database and its user. Returns their IDs and the .env values to write.
|
|
5384
5391
|
*/
|
|
@@ -5392,10 +5399,15 @@ async function applyDatabase(file, plan, state, serverId, ctx, options) {
|
|
|
5392
5399
|
let databaseId = state.databases?.find((db) => db.name === file.database.name)?.id;
|
|
5393
5400
|
for (const change of plan.changes) if (change.action === "create-database") {
|
|
5394
5401
|
options.onChange?.(change);
|
|
5395
|
-
|
|
5402
|
+
const id = (await createDatabase({
|
|
5396
5403
|
server_id: serverId,
|
|
5397
5404
|
name: change.name
|
|
5398
5405
|
}, ctx)).data.id;
|
|
5406
|
+
await waitForInstalled(async () => (await getDatabase({
|
|
5407
|
+
server_id: serverId,
|
|
5408
|
+
id: String(id)
|
|
5409
|
+
}, ctx)).data, (database) => new ApplyError(`Database ${change.name} is ${database.status} on Forge, not installed`, ["Run forge sites apply again once the database is installed"]), options);
|
|
5410
|
+
databaseId = id;
|
|
5399
5411
|
} else if (change.action === "create-database-user") {
|
|
5400
5412
|
options.onChange?.(change);
|
|
5401
5413
|
const password = (options.generatePassword ?? generatePassword)();
|
|
@@ -5405,6 +5417,10 @@ async function applyDatabase(file, plan, state, serverId, ctx, options) {
|
|
|
5405
5417
|
password,
|
|
5406
5418
|
...databaseId === void 0 ? {} : { database_ids: [databaseId] }
|
|
5407
5419
|
}, ctx);
|
|
5420
|
+
await waitForInstalled(async () => (await getDatabaseUser({
|
|
5421
|
+
server_id: serverId,
|
|
5422
|
+
id: String(user.data.id)
|
|
5423
|
+
}, ctx)).data, (created) => new ApplyError(`Database user ${change.name} is ${created.status} on Forge, not installed`, [`The database user ${change.name} exists on Forge, but its password was not saved`, `Delete the database user ${change.name} on Forge before you run forge sites apply again`]), options);
|
|
5408
5424
|
ids.database_user_id = String(user.data.id);
|
|
5409
5425
|
const keys = databaseEnvKeys(file.database);
|
|
5410
5426
|
env.set(keys.name, change.database);
|
|
@@ -5566,6 +5582,9 @@ async function applySiteFile(file, serverId, ctx, options = {}) {
|
|
|
5566
5582
|
server_id: serverId,
|
|
5567
5583
|
type: file.type,
|
|
5568
5584
|
name: file.domain,
|
|
5585
|
+
domain_mode: "custom",
|
|
5586
|
+
www_redirect_type: "none",
|
|
5587
|
+
allow_wildcard_subdomains: false,
|
|
5569
5588
|
...settings.php_version ? { php_version: settings.php_version } : {},
|
|
5570
5589
|
...settings.web_directory ? { web_directory: settings.web_directory } : {},
|
|
5571
5590
|
...settings.source_control_provider ? { source_control_provider: settings.source_control_provider } : {},
|
|
@@ -6796,7 +6815,7 @@ function isVersionRequest({ command, options }) {
|
|
|
6796
6815
|
}
|
|
6797
6816
|
//#endregion
|
|
6798
6817
|
//#region src/cli.ts
|
|
6799
|
-
var VERSION = "0.5.
|
|
6818
|
+
var VERSION = "0.5.6";
|
|
6800
6819
|
function showHelp() {
|
|
6801
6820
|
console.log(`
|
|
6802
6821
|
${colors.bold("forge")} v${VERSION}
|