This document provides guidelines for contributing to the awesome-database-backup project.
First, thank you very much for your contributions! 🎉
For a detailed understanding of the project architecture, please refer to ARCHITECTURE.md.
You can write issues and PRs in English or Japanese.
- Make sure to post PRs based on the latest master branch.
- Please make sure to pass the test suite before posting your PR.
- Run
yarn test
- Run
When implementing a command for a new database:
-
Inherit from the appropriate base class
class NewDBBackupCommand extends BackupCommand { // ... }
-
Implement abstract methods
async dumpDB(options: IBackupCommandOption): Promise<{ stdout: string, stderr: string, dbDumpFilePath: string }> { // Implement database-specific dump process }
-
Add options as needed
addBackupOptions(): this { return super.addBackupOptions() .addOption( new Option( '--new-option <VALUE>', 'Description of the new option', ) ); }
When implementing a new storage service client:
-
Implement the
IStorageServiceClient
interfaceclass NewStorageServiceClient implements IStorageServiceClient { // ... }
-
Implement all required methods
async exists(url: string): Promise<boolean> { // Implementation } async listFiles(url: string, options?: any): Promise<string[]> { // Implementation } // Other methods
-
Register the new client in the factory
// factory.ts export function storageServiceClientFactory( type: StorageServiceClientType, options: any, ): IStorageServiceClient { const factoryMap: { type: StorageServiceClientType, factory: any }[] = [ // Existing entries { type: 'NEW', factory: (options: any) => new NewStorageServiceClient(options) }, ]; // ... }
Command options are defined as interfaces:
export interface INewCommandOption extends ICommonCommandOption {
newOption1: string,
newOption2?: number,
// Other options
}
Catch errors appropriately and log them:
try {
// Process
} catch (e: any) {
logger.error(`An error occurred: ${e.message}`);
// Re-throw exception if necessary
throw e;
}
Each command must have corresponding tests:
- Create test files in the
__tests__
directory - Implement tests using Jest
- Utilize test utility packages
describe('NewDBBackupCommand', () => {
it('should backup database', async () => {
// Test implementation
});
// Other tests
});
Tests should cover the following patterns:
-
Test for when help option is specified
describe('when option --help is specified', () => { const commandLine = `${execBackupCommand} --help`; it('show help messages', async() => { expect(await exec(commandLine)).toEqual({ stdout: expect.stringContaining('Usage:'), stderr: '', }); }); });
-
Error test for when required options are not specified
describe('when no option is specified', () => { const commandLine = `${execBackupCommand}`; it('throw error message', async() => { await expect(exec(commandLine)).rejects.toThrowError( /required option '--target-bucket-url <TARGET_BUCKET_URL> \*\*MANDATORY\*\*' not specified/, ); }); });
-
Normal case test for when valid options are specified
describe('when valid S3 options are specified', () => { beforeEach(cleanTestS3Bucket); beforeEach(prepareTestDB); it('backup database in bucket', async() => { expect(await exec(commandLine)).toEqual({ stdout: expect.stringMatching(/=== backup.ts started at .* ===/), stderr: '', }); }); });
-
Test for when special options like stream mode are specified
Test utility packages are available:
-
@awesome-database-backup/storage-service-test
: Test utilities for storage services (S3, GCS)- Preparation of test buckets
- Cleanup of buckets
- Listing files in buckets
-
@awesome-database-backup/*-test
: Test utilities for each database- Preparation of test databases
- Insertion of test data
- Providing connection information
For version management, use the bump-version
script:
# Increase patch version
npm run bump-version:patch
# Increase minor version
npm run bump-version:minor
# Increase major version
npm run bump-version:major
Versioning is implemented in the misc/bump-versions
package:
-
Version update flow:
- Update the version in
package.json
for each package - Update dependency versions
- Create commit and tag
- Update the version in
-
Configuration file:
.bump-versionsrc.js
module.exports = { // Packages to update versions for packages: [ 'apps/*', 'packages/*', ], // Commit message after version update commitMessage: 'chore: bump version to %s', // Tag after version update tagName: 'v%s', };
-
Semantic versioning:
- Patch version (x.y.Z): Bug fixes and small changes
- Minor version (x.Y.z): Backward-compatible feature additions
- Major version (X.y.z): Backward-incompatible changes
-
Work on development branch
- Implement feature additions or bug fixes
- Run tests to verify functionality
-
Update version
# Update version according to the type of change npm run bump-version:patch # or :minor, :major
-
Merge to release branch
- Merge to
stable
branch - Verify that CI tests pass
- Merge to
-
Create release tag
- Use tag automatically created during version update
- Or manually create tag:
git tag v0.3.2
-
Create release notes
- Use GitHub Releases
- Document major changes