storyblok-backup 0.0.1 → 0.0.3
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 +16 -11
- package/bin/storyblok-backup.mjs +23 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -27,12 +27,13 @@ The script will fetch the following resources of a Storyblok space using the Man
|
|
|
27
27
|
## Installation
|
|
28
28
|
|
|
29
29
|
```shell
|
|
30
|
-
# install globally
|
|
31
|
-
$ npm install -g storyblok-backup
|
|
32
30
|
|
|
33
|
-
#
|
|
31
|
+
# simply auto-download and run via npx
|
|
34
32
|
$ npx storyblok-backup
|
|
35
33
|
|
|
34
|
+
# or install globally
|
|
35
|
+
$ npm install -g storyblok-backup
|
|
36
|
+
|
|
36
37
|
# or install for project using npm
|
|
37
38
|
$ npm install storyblok-backup
|
|
38
39
|
|
|
@@ -45,6 +46,8 @@ $ pnpm add storyblok-backup
|
|
|
45
46
|
|
|
46
47
|
## Usage
|
|
47
48
|
|
|
49
|
+
Call `npx storyblok-backup` with the following options:
|
|
50
|
+
|
|
48
51
|
### Options
|
|
49
52
|
|
|
50
53
|
```text
|
|
@@ -69,7 +72,7 @@ $ pnpm add storyblok-backup
|
|
|
69
72
|
npx storyblok-backup --token 1234567890abcdef --space 12345
|
|
70
73
|
```
|
|
71
74
|
|
|
72
|
-
This will create the folder `./.output` and fetch all resources sorted into folders.
|
|
75
|
+
This will create the folder `./.output/backup` and fetch all resources sorted into folders.
|
|
73
76
|
|
|
74
77
|
### Maximal example
|
|
75
78
|
|
|
@@ -79,12 +82,13 @@ npx storyblok-backup \
|
|
|
79
82
|
--space 12345 \
|
|
80
83
|
--with-asset-files \
|
|
81
84
|
--output-dir ./my-dir \
|
|
85
|
+
--force \
|
|
82
86
|
--create-zip \
|
|
83
87
|
--zip-prefix daily \
|
|
84
88
|
--verbose
|
|
85
89
|
```
|
|
86
90
|
|
|
87
|
-
This will create the folder `./my-dir`, fetch all resources (incl. the original file assets) sorted into folders, zip them to `./my-dir/daily-Y-m-d-H-i-s.zip`, and log every written file to console.
|
|
91
|
+
This will create the folder `./my-dir/backup`, fetch all resources (incl. the original file assets) sorted into folders, zip them to `./my-dir/daily-Y-m-d-H-i-s.zip`, and log every written file to console.
|
|
88
92
|
|
|
89
93
|
## Continuous Integration
|
|
90
94
|
|
|
@@ -100,15 +104,17 @@ on:
|
|
|
100
104
|
- cron: '0 0 * * 0'
|
|
101
105
|
|
|
102
106
|
jobs:
|
|
103
|
-
|
|
107
|
+
backup:
|
|
104
108
|
runs-on: ubuntu-latest
|
|
109
|
+
permissions:
|
|
110
|
+
actions: write
|
|
105
111
|
|
|
106
112
|
steps:
|
|
107
113
|
- name: Perform Backup
|
|
108
114
|
env:
|
|
109
115
|
STORYBLOK_OAUTH_TOKEN: ${{ secrets.STORYBLOK_OAUTH_TOKEN }}
|
|
110
116
|
STORYBLOK_SPACE_ID: ${{ secrets.STORYBLOK_SPACE_ID }}
|
|
111
|
-
run: npx storyblok-backup --token $STORYBLOK_OAUTH_TOKEN --space $STORYBLOK_SPACE_ID
|
|
117
|
+
run: npx storyblok-backup --token $STORYBLOK_OAUTH_TOKEN --space $STORYBLOK_SPACE_ID
|
|
112
118
|
|
|
113
119
|
- name: Delete Old Artifacts
|
|
114
120
|
uses: actions/github-script@v6
|
|
@@ -130,18 +136,17 @@ jobs:
|
|
|
130
136
|
})
|
|
131
137
|
})
|
|
132
138
|
|
|
133
|
-
- name: Copy Artifact
|
|
134
|
-
run: mkdir artifact && cp ./.output/*.zip artifact
|
|
135
|
-
|
|
136
139
|
- name: Upload Artifact
|
|
137
140
|
uses: actions/upload-artifact@v3
|
|
138
141
|
with:
|
|
139
142
|
name: weekly-backup
|
|
140
|
-
path:
|
|
143
|
+
path: .output
|
|
141
144
|
```
|
|
142
145
|
|
|
143
146
|
Make sure, to set the secrets `STORYBLOK_OAUTH_TOKEN` and `STORYBLOK_SPACE_ID` in your repository settings.
|
|
144
147
|
|
|
148
|
+
Note that artifact manipulation requires the `actions: write` permission for the workflow. The workflow above has this permission set already.
|
|
149
|
+
|
|
145
150
|
If you create multiple workflows for daily, weekly and monthly backups, by changing the cron-schedule and the two occurrences of the artifact name `weekly-backup`, you will always have exactly one daily, weekly and monthly backup.
|
|
146
151
|
|
|
147
152
|
Also keep in mind, that there is a limit on artifact storage and runner minutes ([see GitHub docs](https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions#included-storage-and-minutes)).
|
package/bin/storyblok-backup.mjs
CHANGED
|
@@ -38,8 +38,11 @@ MAXIMAL EXAMPLE
|
|
|
38
38
|
$ npx storyblok-backup \\
|
|
39
39
|
--token 1234567890abcdef \\
|
|
40
40
|
--space 12345 \\
|
|
41
|
+
--with-asset-files \\
|
|
41
42
|
--output-dir ./backup \\
|
|
42
|
-
--
|
|
43
|
+
--force \\
|
|
44
|
+
--create-zip \\
|
|
45
|
+
--zip-prefix daily \\
|
|
43
46
|
--verbose
|
|
44
47
|
`)
|
|
45
48
|
process.exit(0)
|
|
@@ -61,6 +64,8 @@ const verbose = 'verbose' in args
|
|
|
61
64
|
|
|
62
65
|
const outputDir = args['output-dir'] || './.output'
|
|
63
66
|
|
|
67
|
+
const backupDir = `${outputDir}/backup`
|
|
68
|
+
|
|
64
69
|
if (fs.existsSync(outputDir) && !('force' in args)) {
|
|
65
70
|
console.log(
|
|
66
71
|
`Error: Output directory "${outputDir}" already exists. Use --force to delete and recreate it (POSSIBLY DANGEROUS!).`
|
|
@@ -102,7 +107,7 @@ if (fs.existsSync(outputDir)) {
|
|
|
102
107
|
}
|
|
103
108
|
|
|
104
109
|
// Create output directories
|
|
105
|
-
fs.mkdirSync(
|
|
110
|
+
fs.mkdirSync(backupDir, { recursive: true })
|
|
106
111
|
|
|
107
112
|
const resources = [
|
|
108
113
|
'stories',
|
|
@@ -121,13 +126,22 @@ const resources = [
|
|
|
121
126
|
'workflows',
|
|
122
127
|
'releases',
|
|
123
128
|
]
|
|
124
|
-
resources.forEach((resource) => fs.mkdirSync(`${
|
|
129
|
+
resources.forEach((resource) => fs.mkdirSync(`${backupDir}/${resource}`))
|
|
125
130
|
|
|
126
131
|
// Function to perform a default fetch
|
|
127
|
-
const defaultFetch = async (type, folder, fileField) => {
|
|
132
|
+
const defaultFetch = async (type, folder, fileField, fileFieldObject) => {
|
|
128
133
|
await StoryblokMAPI.getAll(`spaces/${spaceId}/${type}`)
|
|
129
134
|
.then((items) => {
|
|
130
|
-
|
|
135
|
+
if (type === 'datasources') {
|
|
136
|
+
console.log(items)
|
|
137
|
+
}
|
|
138
|
+
items.forEach((item) =>
|
|
139
|
+
writeJson(
|
|
140
|
+
folder,
|
|
141
|
+
fileFieldObject ? item[fileFieldObject][fileField] : item[fileField],
|
|
142
|
+
item
|
|
143
|
+
)
|
|
144
|
+
)
|
|
131
145
|
})
|
|
132
146
|
.catch((error) => {
|
|
133
147
|
throw error
|
|
@@ -136,7 +150,7 @@ const defaultFetch = async (type, folder, fileField) => {
|
|
|
136
150
|
|
|
137
151
|
// Function to write a file
|
|
138
152
|
const writeJson = (folder, file, content) => {
|
|
139
|
-
let outputFile =
|
|
153
|
+
let outputFile = backupDir
|
|
140
154
|
if (folder !== null) {
|
|
141
155
|
outputFile += `/${folder}`
|
|
142
156
|
}
|
|
@@ -152,7 +166,7 @@ const writeJson = (folder, file, content) => {
|
|
|
152
166
|
// Function to download a file
|
|
153
167
|
const downloadFile = async (type, name, url) => {
|
|
154
168
|
const res = await fetch(url)
|
|
155
|
-
const outputFile = `${
|
|
169
|
+
const outputFile = `${backupDir}/${type}/${name}`
|
|
156
170
|
const fileStream = fs.createWriteStream(outputFile, { flags: 'wx' })
|
|
157
171
|
await finished(Readable.fromWeb(res.body).pipe(fileStream))
|
|
158
172
|
if (verbose) console.log(`Written file ${outputFile}`)
|
|
@@ -244,7 +258,7 @@ await defaultFetch('tasks', 'tasks', 'id')
|
|
|
244
258
|
|
|
245
259
|
// Fetch all activities
|
|
246
260
|
console.log(`Fetching activities`)
|
|
247
|
-
await defaultFetch('activities', 'activities', 'id')
|
|
261
|
+
await defaultFetch('activities', 'activities', 'id', 'activity')
|
|
248
262
|
|
|
249
263
|
// Fetch all presets
|
|
250
264
|
console.log(`Fetching presets`)
|
|
@@ -274,7 +288,7 @@ await defaultFetch('releases', 'releases', 'id')
|
|
|
274
288
|
if ('create-zip' in args) {
|
|
275
289
|
console.log(`Creating zip file`)
|
|
276
290
|
await zipLib
|
|
277
|
-
.archiveFolder(
|
|
291
|
+
.archiveFolder(backupDir, filePath)
|
|
278
292
|
.then(
|
|
279
293
|
function () {
|
|
280
294
|
console.log(`Backup file '${filePath}' successfully created.`)
|