dxfl 0.3.1 → 0.4.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/CHANGELOG.md +10 -0
- package/README.md +8 -2
- package/dist/auth.js +5 -0
- package/dist/bucket.js +15 -11
- package/dist/deploy.js +1 -3
- package/dist/index.js +3 -2
- package/dist/website_config.js +10 -2
- package/doc/workflows/gh-actions.yml +1 -1
- package/doc/workflows/woodpecker.yml +1 -1
- package/package.json +10 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
# v0.4.0
|
|
2
|
+
|
|
3
|
+
- `deploy`: allow to specify a custom config file with `--config-file` or `-c`
|
|
4
|
+
|
|
5
|
+
# v0.3.2
|
|
6
|
+
|
|
7
|
+
- update `@aws-sdk/client-s3` 3.983.0 → 3.1004.0
|
|
8
|
+
- `deploy`: fix failed request not being retried
|
|
9
|
+
- AWS\_\* environment variables now override guichet credentials
|
|
10
|
+
|
|
1
11
|
# v0.3.1
|
|
2
12
|
|
|
3
13
|
- fix `deuxfleurs.toml`: always pass the user-provided value of index_page to garage
|
package/README.md
CHANGED
|
@@ -40,6 +40,12 @@ Or only display the changes without applying them, with the `--dry-run` option:
|
|
|
40
40
|
dxfl deploy example.com _public --dry-run
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
+
You can also specify a custom TOML configuration file to use instead of the default `deuxfleurs.toml`, with the `--config-file` option:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
dxfl deploy example.com _public --config-file custom.toml
|
|
47
|
+
```
|
|
48
|
+
|
|
43
49
|
Use the `empty` command to delete all files from a website (required before deleting it):
|
|
44
50
|
|
|
45
51
|
```
|
|
@@ -54,10 +60,10 @@ dxfl inspect example.com
|
|
|
54
60
|
|
|
55
61
|
## Website configuration
|
|
56
62
|
|
|
57
|
-
`dxfl deploy` reads a `deuxfleurs.toml`
|
|
63
|
+
`dxfl deploy` reads a TOML configuration file, `deuxfleurs.toml` by default (if it exists in the current directory), or the one specified with the `--config-file` option.
|
|
58
64
|
This file can be used to specify website configuration metadata such as redirections.
|
|
59
65
|
|
|
60
|
-
Your
|
|
66
|
+
Your configuration file should follow the following structure:
|
|
61
67
|
|
|
62
68
|
```toml
|
|
63
69
|
# Filename added after URLs that point to directories.
|
package/dist/auth.js
CHANGED
|
@@ -109,6 +109,11 @@ export function openApiConf() {
|
|
|
109
109
|
}
|
|
110
110
|
export function login(username) {
|
|
111
111
|
return __awaiter(this, void 0, void 0, function* () {
|
|
112
|
+
if (username == undefined) {
|
|
113
|
+
username = yield read({
|
|
114
|
+
prompt: "username: ",
|
|
115
|
+
});
|
|
116
|
+
}
|
|
112
117
|
const password = yield read({
|
|
113
118
|
prompt: "password: ",
|
|
114
119
|
silent: true,
|
package/dist/bucket.js
CHANGED
|
@@ -7,7 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import fs from "fs";
|
|
10
|
+
import fs from "fs/promises";
|
|
11
11
|
import mime from "mime";
|
|
12
12
|
import { DeleteObjectCommand, DeleteObjectsCommand, HeadObjectCommand, ListObjectsV2Command, PutObjectCommand, S3Client, } from "@aws-sdk/client-s3";
|
|
13
13
|
import { PromisePool } from "@supercharge/promise-pool";
|
|
@@ -17,19 +17,18 @@ import { GuichetApi } from "./guichet.js";
|
|
|
17
17
|
import { parseEtag, toChunks, formatBytesHuman } from "./utils.js";
|
|
18
18
|
export function getBucketCredentials(name) {
|
|
19
19
|
return __awaiter(this, void 0, void 0, function* () {
|
|
20
|
+
const creds = credentialsFromEnv();
|
|
21
|
+
if (creds !== undefined) {
|
|
22
|
+
process.stdout.write("Using credentials from environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY\n");
|
|
23
|
+
return creds;
|
|
24
|
+
}
|
|
20
25
|
if (yield apiConfExists()) {
|
|
21
26
|
const guichet = new GuichetApi(yield openApiConf());
|
|
22
27
|
return yield credentialsFromApi(guichet, name);
|
|
23
28
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
throw new ErrorMsg("Failed to load credentials.\n" +
|
|
28
|
-
"You need to run 'dxfl login', " +
|
|
29
|
-
"or define the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables.");
|
|
30
|
-
}
|
|
31
|
-
return creds;
|
|
32
|
-
}
|
|
29
|
+
throw new ErrorMsg("Failed to load credentials.\n" +
|
|
30
|
+
"You need to run 'dxfl login', " +
|
|
31
|
+
"or define the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables.");
|
|
33
32
|
});
|
|
34
33
|
}
|
|
35
34
|
function credentialsFromEnv() {
|
|
@@ -153,7 +152,12 @@ export function uploadFile(bucket, s3Path, localPath) {
|
|
|
153
152
|
if (ContentType && ContentType.startsWith("text/")) {
|
|
154
153
|
ContentType = ContentType + "; charset=utf-8";
|
|
155
154
|
}
|
|
156
|
-
|
|
155
|
+
// NB: we read the entire file into memory instead of creating a stream from
|
|
156
|
+
// the file (which would allow streaming the data). Indeed, using a stream
|
|
157
|
+
// results in transcient network errors being throwned instead of being
|
|
158
|
+
// retried by the AWS SDK: https://github.com/aws/aws-sdk-js-v3/issues/6770
|
|
159
|
+
// which we want to avoid...
|
|
160
|
+
const Body = yield fs.readFile(localPath);
|
|
157
161
|
const params = { Bucket: bucket.name, Key: s3Path, Body, ContentType };
|
|
158
162
|
yield wrapS3Call(`upload "${s3Path}"`, [200], () => bucket.client.send(new PutObjectCommand(params)));
|
|
159
163
|
});
|
package/dist/deploy.js
CHANGED
|
@@ -323,10 +323,8 @@ export function deploy(website, localFolder, options) {
|
|
|
323
323
|
if (options.dryRun && options.yes) {
|
|
324
324
|
throw new ErrorMsg("options --yes and --dry-run cannot be passed at the same time");
|
|
325
325
|
}
|
|
326
|
-
// TODO: make this configurable
|
|
327
|
-
const website_config_path = "deuxfleurs.toml";
|
|
328
326
|
// Read and validate the local configuration file before doing anything else
|
|
329
|
-
const localWebsiteConfig = yield readConfigFile(
|
|
327
|
+
const localWebsiteConfig = yield readConfigFile(options.configFile);
|
|
330
328
|
process.stdout.write("Fetching the website configuration and metadata...\n");
|
|
331
329
|
const [localFiles, [bucket, remoteFiles, remoteWebsiteConfig]] = yield Promise.all([
|
|
332
330
|
// Get paths & size of the local files to deploy
|
package/dist/index.js
CHANGED
|
@@ -6,11 +6,11 @@ import { deploy } from "./deploy.js";
|
|
|
6
6
|
import { empty } from "./empty.js";
|
|
7
7
|
import { vhostsList } from "./vhosts.js";
|
|
8
8
|
import { inspect } from "./inspect.js";
|
|
9
|
-
program.name("dxfl").description("Deuxfleurs CLI tool").version("0.
|
|
9
|
+
program.name("dxfl").description("Deuxfleurs CLI tool").version("0.4.0");
|
|
10
10
|
program
|
|
11
11
|
.command("login")
|
|
12
12
|
.description("Link your Deuxfleurs account with this tool.")
|
|
13
|
-
.argument("
|
|
13
|
+
.argument("[username]", "your account username")
|
|
14
14
|
.action(username => withHandleErrors(() => login(username)));
|
|
15
15
|
program
|
|
16
16
|
.command("list")
|
|
@@ -29,6 +29,7 @@ program
|
|
|
29
29
|
.argument("<local_folder>", "your local folder")
|
|
30
30
|
.option("-n, --dry-run", "do a trial run without making actual changes")
|
|
31
31
|
.option("-y, --yes", "apply the changes without asking for confirmation")
|
|
32
|
+
.option("-c, --config-file <path>", "apply a custom TOML config file")
|
|
32
33
|
.action((website, localFolder, options) => withHandleErrors(() => deploy(website, localFolder, options)));
|
|
33
34
|
program
|
|
34
35
|
.command("empty")
|
package/dist/website_config.js
CHANGED
|
@@ -54,7 +54,15 @@ export function equalCorsRules(c1, c2) {
|
|
|
54
54
|
// Parsing: TOML -> untyped object
|
|
55
55
|
function readConfigFileObject(filename) {
|
|
56
56
|
return __awaiter(this, void 0, void 0, function* () {
|
|
57
|
-
if (
|
|
57
|
+
if (filename != undefined) {
|
|
58
|
+
if (!fs.existsSync(filename)) {
|
|
59
|
+
throw new ErrorMsg(`${filename} configuration file not found`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else if (fs.existsSync("deuxfleurs.toml")) {
|
|
63
|
+
filename = "deuxfleurs.toml";
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
58
66
|
return {};
|
|
59
67
|
}
|
|
60
68
|
let strConf;
|
|
@@ -485,7 +493,7 @@ export function putCorsRules(bucket, cors_rules) {
|
|
|
485
493
|
ExposeHeaders: rule.expose_headers,
|
|
486
494
|
});
|
|
487
495
|
}
|
|
488
|
-
yield wrapS3Call(`
|
|
496
|
+
yield wrapS3Call(`write the bucket CORS config`, [200], () => bucket.client.send(new PutBucketCorsCommand({
|
|
489
497
|
Bucket: bucket.name,
|
|
490
498
|
CORSConfiguration: { CORSRules },
|
|
491
499
|
})));
|
|
@@ -3,7 +3,7 @@ name: Deploy with GitHub Actions
|
|
|
3
3
|
# You will need to:
|
|
4
4
|
# 1. Get (from Guichet web interface):
|
|
5
5
|
# - Your access keys (ID and secret): in the "S3" tab of your website
|
|
6
|
-
# - The website id: your sub-domain (
|
|
6
|
+
# - The website id: your sub-domain (e.g. something.deuxfleurs.eu|page) or your full custom domain (e.g. your-domain.com)
|
|
7
7
|
# 2. Setup the access keys as secrets in GitHub web interface (https://docs.github.com/en/actions/how-tos/writing-workflows/choosing-what-your-workflow-does/using-secrets-in-github-actions), named in this example key_id and key_secret
|
|
8
8
|
# 3. If you use a deuxfleurs.toml config, be sure the dxfl deploy command is launch in the current directory its in.
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
# You will need to:
|
|
4
4
|
# 1. Get (from Guichet web interface):
|
|
5
5
|
# - Your access keys (ID and secret): in the "S3" tab of your website
|
|
6
|
-
# - The website id: your sub-domain (
|
|
6
|
+
# - The website id: your sub-domain (e.g. something.deuxfleurs.eu|page) or your full custom domain (e.g. your-domain.com)
|
|
7
7
|
# 2. Setup the access keys as secrets in Woodpecker web interface (https://woodpecker-ci.org/docs/usage/secrets), named in this example key_id and key_secret
|
|
8
8
|
# 3. If you use a deuxfleurs.toml config, be sure the dxfl deploy command is launch in the current directory its in.
|
|
9
9
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dxfl",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "EUPL-1.2",
|
|
6
6
|
"author": "Deuxfleurs Team <coucou@deuxfleurs.fr>",
|
|
@@ -20,18 +20,18 @@
|
|
|
20
20
|
"prettier-check": "npx prettier . --check"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@aws-sdk/client-s3": "^3.
|
|
24
|
-
"@commander-js/extra-typings": "^
|
|
23
|
+
"@aws-sdk/client-s3": "^3.1004.0",
|
|
24
|
+
"@commander-js/extra-typings": "^14.0.0",
|
|
25
25
|
"@supercharge/promise-pool": "^3.2.0",
|
|
26
|
-
"@types/node": "^
|
|
26
|
+
"@types/node": "^25.2.1",
|
|
27
27
|
"cli-color": "^2.0.4",
|
|
28
|
-
"commander": "^
|
|
29
|
-
"fast-uri": "^3.0
|
|
28
|
+
"commander": "^14.0.3",
|
|
29
|
+
"fast-uri": "^3.1.0",
|
|
30
30
|
"guichet-sdk-ts": "^0.1.0",
|
|
31
|
-
"mime": "^4.0
|
|
32
|
-
"read": "^
|
|
33
|
-
"smol-toml": "^1.
|
|
34
|
-
"typescript": "^5.
|
|
31
|
+
"mime": "^4.1.0",
|
|
32
|
+
"read": "^5.0.1",
|
|
33
|
+
"smol-toml": "^1.6.0",
|
|
34
|
+
"typescript": "^5.9.3",
|
|
35
35
|
"zod": "^3.24.4",
|
|
36
36
|
"zod-validation-error": "^3.4.1"
|
|
37
37
|
},
|