Skip to content

Commit

Permalink
BYOR: Add vip app deploy (#1560)
Browse files Browse the repository at this point in the history
* BYOR: Add `vip deploy app`

* Add logic to rename on upload to prevent file being overwritten

* Add --message parameter

* Add --force to options

* Add validation checks + tests

* Mekk typescript

* Add constant & remove `currentUserCanDeployForApp()`

* `gates()`: Add check to ensure file is compressed before uploading

* Instead of fs copying, just change key on AWS upload and change deploy message when done

* Rename cmd to `vip app deploy`

* Allow hashing with sha256

* Rename steps

* Adjust to sentence case

---------

Co-authored-by: Caleb Burks <[email protected]>
  • Loading branch information
rebeccahum and WPprodigy authored Dec 18, 2023
1 parent 756ff79 commit 5d862dd
Show file tree
Hide file tree
Showing 11 changed files with 572 additions and 13 deletions.
95 changes: 95 additions & 0 deletions __tests__/bin/vip-app-deploy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { appDeployCmd } from '../../src/bin/vip-app-deploy';
import * as exit from '../../src/lib/cli/exit';
import { uploadImportSqlFileToS3 } from '../../src/lib/client-file-uploader';
import { gates, promptToContinue } from '../../src/lib/manual-deploy/manual-deploy';
import { validateDeployFileExt, validateFilename } from '../../src/lib/validations/manual-deploy';

jest.mock( '../../src/lib/client-file-uploader', () => ( {
...jest.requireActual( '../../src/lib/client-file-uploader' ),
getFileMeta: jest
.fn()
.mockResolvedValue( { fileName: '/vip/skeleton.zip', basename: 'skeleton.zip' } ),
uploadImportSqlFileToS3: jest.fn(),
} ) );

jest.mock( '../../src/lib/manual-deploy/manual-deploy', () => ( {
gates: jest.fn(),
renameFile: jest.fn(),
promptToContinue: jest.fn().mockResolvedValue( true ),
} ) );

jest.mock( '../../src/lib/cli/command', () => {
const commandMock = {
argv: () => commandMock,
examples: () => commandMock,
option: () => commandMock,
};
return jest.fn( () => commandMock );
} );

const exitSpy = jest.spyOn( exit, 'withError' );
jest.spyOn( process, 'exit' ).mockImplementation( () => {} );
jest.spyOn( console, 'error' ).mockImplementation( () => {} );

const args = [ '/vip/skeleton.zip' ];
const opts = {
app: {
id: 1,
organization: {
id: 2,
},
},
env: {
id: 3,
type: 'develop',
},
force: true,
};

describe( 'vip-app-deploy', () => {
describe( 'validations', () => {
beforeEach( async () => {
exitSpy.mockClear();
} );

it.each( [ '$t2.tar.gz', 'vip-go!!skeleton.zip', '1-(vip).tgz' ] )(
'fails if the deploy file has has invalid characters',
async basename => {
validateFilename( basename );
expect( exitSpy ).toHaveBeenCalledWith(
'Error: The characters used in the name of a file for manual deploys are limited to [0-9,a-z,A-Z,-,_,.]'
);
}
);

it.each( [ 'test-repo.rar', 'vip-go-skeleton.sql', 'vip.test' ] )(
'fails if the deploy file has an invalid extension',
async basename => {
validateDeployFileExt( basename );
expect( exitSpy ).toHaveBeenCalledWith(
'Invalid file extension. Please provide a .zip, .tar.gz, or a .tgz file.'
);
}
);

it.each( [ 'test-repo.tar.gz', 'vip-go-skeleton.zip', 'vip.tgz' ] )(
'passes if the deploy file has a valid extension',
async basename => {
validateDeployFileExt( basename );
expect( exitSpy ).not.toHaveBeenCalled();
}
);
} );

describe( 'appDeployCmd', () => {
it( 'should call expected functions', async () => {
await appDeployCmd( args, opts );

expect( gates ).toHaveBeenCalledTimes( 1 );

expect( promptToContinue ).not.toHaveBeenCalled();

expect( uploadImportSqlFileToS3 ).toHaveBeenCalledTimes( 1 );
} );
} );
} );
8 changes: 4 additions & 4 deletions __tests__/lib/client-file-uploader.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* @format
*/

import { getFileMD5Hash, getFileMeta, getPartBoundaries } from '../../src/lib/client-file-uploader';
import { getFileHash, getFileMeta, getPartBoundaries } from '../../src/lib/client-file-uploader';

describe( 'client-file-uploader', () => {
describe( 'getFileMeta()', () => {
Expand All @@ -27,16 +27,16 @@ describe( 'client-file-uploader', () => {
} );
} );

describe( 'getFileMD5Hash()', () => {
describe( 'getFileHash()', () => {
it( 'should get hash from a 67mb sql file', async () => {
const fileName = '__fixtures__/client-file-uploader/db-dump-ipsum-67mb.sql';
const md5 = await getFileMD5Hash( fileName );
const md5 = await getFileHash( fileName );
expect( md5 ).toBe( '6a051288a7848e3fb3571af220fc455a' );
} );

it( 'should get hash from a 5+mb text file', async () => {
const fileName = '__fixtures__/client-file-uploader/numerical-test-file-5.24mb.txt';
const md5 = await getFileMD5Hash( fileName );
const md5 = await getFileHash( fileName );
expect( md5 ).toBe( '6f18fdff4f9f9926989e0816741aa2ba' );
} );
} );
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"vip": "dist/bin/vip.js",
"vip-app": "dist/bin/vip-app.js",
"vip-app-list": "dist/bin/vip-app-list.js",
"vip-app-deploy": "dist/bin/vip-app-deploy.js",
"vip-backup": "dist/bin/vip-backup.js",
"vip-backup-db": "dist/bin/vip-backup-db.js",
"vip-cache": "dist/bin/vip-cache.js",
Expand Down
15 changes: 15 additions & 0 deletions src/bin/vip-app-deploy.generated.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import * as Types from '../graphqlTypes';

export type StartDeployMutationVariables = Types.Exact< {
input?: Types.InputMaybe< Types.AppEnvironmentDeployInput >;
} >;

export type StartDeployMutation = {
__typename?: 'Mutation';
startDeploy?: {
__typename?: 'AppEnvironmentDeployPayload';
message?: string | null;
success?: boolean | null;
app?: { __typename?: 'App'; id?: number | null; name?: string | null } | null;
} | null;
};
Loading

0 comments on commit 5d862dd

Please sign in to comment.