-
Notifications
You must be signed in to change notification settings - Fork 444
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(backup): add new command dataset backup for server-side backups #5571
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
1 Ignored Deployment
|
69c224d
to
e260037
Compare
New dependencies detected. Learn more about Socket for GitHub ↗︎
|
e260037
to
b5031c9
Compare
5c6cd3f
to
e7bd85a
Compare
a6e4371
to
b9d56e0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Left a few comments, mostly nice-to-haves.
import {CliCommandGroupDefinition} from '@sanity/cli' | ||
|
||
// defaultApiVersion is the backend API version used for dataset backup. | ||
export const defaultApiVersion = 'vX' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this not be a proper API version instead of vX
? If it's intentional to keep it at vX, can you add a comment explaining why and what it would take to move it to an official version?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be released with vX
Content Lake API version. Added the reason inline:
// First version of the backup API is vX since this feature is not yet released
// and formal API documentation is pending.
import cleanupTmpDir from '../../actions/backup/cleanupTmpDir' | ||
import {defaultApiVersion} from './backupGroup' | ||
|
||
const debug = require('debug')('sanity:backup') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a blocker, but ideally this should be
const debug = require('debug')('sanity:backup') | |
import createDebug from 'debug' | |
const debug = createDebug('sanity:backup') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed it.
const DEFAULT_DOWNLOAD_CONCURRENCY = 10 | ||
const MAX_DOWNLOAD_CONCURRENCY = 24 | ||
|
||
type DownloadBackupOptions = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Nit, so feel free to ignore: we tend to use interface
when we can)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed type to interface.
// Create a unique temporary directory to store files before bundling them into the archive at outputPath. | ||
// Temporary directories are normally deleted at the end of backup process, any unexpected exit may leave them | ||
// behind, hence it is important to create a unique directory for each attempt. | ||
const tmpOutDir = await mkdtemp(path.join(tmpdir(), `backup-`)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would be great if we could add sanity-
to the tempfile here so we can leave a hint about who made it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Goood point. Added it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
most of them are nit-picky comments or questions. Not a blocker
packages/sanity/src/_internal/cli/actions/backup/chooseBackupIdPrompt.ts
Outdated
Show resolved
Hide resolved
packages/sanity/src/_internal/cli/actions/backup/chooseBackupIdPrompt.ts
Outdated
Show resolved
Hide resolved
packages/sanity/src/_internal/cli/actions/backup/downloadAsset.ts
Outdated
Show resolved
Hide resolved
packages/sanity/src/_internal/cli/actions/backup/fetchNextBackupPage.ts
Outdated
Show resolved
Hide resolved
packages/sanity/src/_internal/cli/actions/backup/resolveApiClient.ts
Outdated
Show resolved
Hide resolved
packages/sanity/src/_internal/cli/commands/backup/downloadBackupCommand.ts
Outdated
Show resolved
Hide resolved
context: CliCommandContext, | ||
args: CliCommandArguments, | ||
): Promise<[SanityClient, DownloadBackupOptions]> { | ||
const flags = args.extOptions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Take a look at this PR I believe we want to use yargs
to parse the flags, it enforces types and in future we want to move to making sure all flags are defined properly. It will also help remove some of the type checking code below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. Updated code to follow this pattern.
helpText, | ||
action: async (args, context) => { | ||
const {output, chalk} = context | ||
const flags = args.extOptions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same comment here, it would be good to re-parse the arguments using yargs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fixed as well.
} catch (error) { | ||
const msg = error.statusCode | ||
? error.response.body.message | ||
: error.message || error.statusMessage |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in latest commit to print the proper error.
…odule namespace in imports, use interface in place of type, handle unhandled rejection
…et backup command, refactor enable/disable commands, fix backup list CLI to use correct response type and error handling
…selection for backup ID and dataset names, add progress bar
…le names that contain a path segment to prevent archiving failure
… spinner, void using long names for temporary dir to prevent hitting max length limit, handle archive warning, enable compression of archived file by default
…rency safe download of documents, refactor code into modules that can be easily tested, improve progress tracking for dataset backup, install progress-stream correctly, address review feedback, fix API usage for list backups
…odule namespace in imports, use interface in place of type, handle unhandled rejection
…response, use yargs to parse CLI flags
6a27918
to
b0622b9
Compare
I have rebased from latest next branch with new linter config and reformatted files in this PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks!
Description
This PR introduces backup command for server-side dataset backups:
sanity backup -h
. This command primarily intended to be a consumer of Backup APIs and has very little client side logic. If you are a Sanity colleague, kindly refer to #prj-dataset-backups for more context.Usage
User experience of interaction with the CLI has been kept very similar to using
sanity export
. The downloaded tar file should be importable throughsanity dataset import
.Interaction with server-side backups
Enable backup for a dataset
Usage
Sample Output
List backups
Usage
Sample Output
Download a backup
Usage
Sample Output
Disable backup for a dataset
Usage
Sample Output
Potential Optimizations
sanity backup download
, we are first iterating over all the backup file and then downloading them. This behaviour may not be scalable when number of files is huge. To handle this, we can start downloading files as soon as we are reading them.sanity backup download
, if it is possible, stream downloaded files directly into the tarball without writing them to disk first.Notes for release
Since we are not marketing this feature at the moment, it is okay to skip these commits from public release notes.