Skip to content

Commit 3c538bc

Browse files
committed
refactor: remove insta_infra_folder input, update CLI and integration logic, add cleanFolder utility
- Removed the `insta_infra_folder` input from action.yml and related code. - Updated CLI to reflect changes in folder handling. - Enhanced integration logic to check for insta CLI installation and install if missing. - Introduced `cleanFolder` utility to ensure fresh state by cleaning specified folders before creating them. - Updated version to 1.2.1 in package.json and cli.js. - Adjusted tests to align with the removal of the insta_infra_folder input and added new tests for cleanFolder and shutdownServices functionality.
1 parent a37a362 commit 3c538bc

13 files changed

Lines changed: 325 additions & 190 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ For example, you can print out the results like below:
310310
```yaml
311311
- name: Run integration tests
312312
id: test-action
313-
uses: data-catering/insta-integration@v1
313+
uses: data-catering/insta-integration@v6
314314
- name: Print Output
315315
id: output
316316
run: |

__tests__/main.test.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ describe('getConfiguration', () => {
5656
beforeEach(() => {
5757
jest.resetAllMocks()
5858
process.env.CONFIGURATION_FILE = 'config.json'
59-
process.env.INSTA_INFRA_FOLDER = '/infra'
6059
process.env.BASE_FOLDER = '/base'
6160
process.env.DATA_CATERER_VERSION = '1.0.0'
6261
})
@@ -65,7 +64,6 @@ describe('getConfiguration', () => {
6564
const config = getConfiguration()
6665
expect(config).toEqual({
6766
applicationConfig: 'config.json',
68-
instaInfraFolder: '/infra',
6967
baseFolder: '/base',
7068
dataCatererVersion: '1.0.0'
7169
})
@@ -75,7 +73,6 @@ describe('getConfiguration', () => {
7573
core.getInput.mockImplementation(name => {
7674
const inputs = {
7775
configuration_file: 'input_config.json',
78-
insta_infra_folder: '/input_infra',
7976
base_folder: '/input_base',
8077
data_caterer_version: '2.0.0'
8178
}
@@ -84,7 +81,6 @@ describe('getConfiguration', () => {
8481
const config = getConfiguration()
8582
expect(config).toEqual({
8683
applicationConfig: 'input_config.json',
87-
instaInfraFolder: '/input_infra',
8884
baseFolder: '/input_base',
8985
dataCatererVersion: '2.0.0'
9086
})

__tests__/util/file.test.js

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ const {
77
cleanAppDoneFiles,
88
checkFileExistsWithTimeout,
99
createFolders,
10-
showLogFileContent
10+
showLogFileContent,
11+
cleanFolder
1112
} = require('../../src/util/file')
1213
const { expect } = require('@jest/globals')
1314
const logger = require('../../src/util/log')
@@ -231,15 +232,66 @@ describe('showLogFileContent', () => {
231232
})
232233
})
233234

235+
describe('cleanFolder', () => {
236+
beforeEach(() => {
237+
jest.resetAllMocks()
238+
jest.spyOn(fs, 'existsSync')
239+
jest.spyOn(fs, 'rmSync')
240+
jest.spyOn(logger, 'debug')
241+
})
242+
243+
it('should remove folder if it exists', () => {
244+
fs.existsSync.mockReturnValue(true)
245+
cleanFolder('/path/to/folder')
246+
expect(fs.rmSync).toHaveBeenCalledWith('/path/to/folder', {
247+
recursive: true,
248+
force: true
249+
})
250+
expect(logger.debug).toHaveBeenCalledWith(
251+
'[Config] Cleaning folder: /path/to/folder'
252+
)
253+
})
254+
255+
it('should not attempt to remove folder if it does not exist', () => {
256+
fs.existsSync.mockReturnValue(false)
257+
cleanFolder('/path/to/nonexistent')
258+
expect(fs.rmSync).not.toHaveBeenCalled()
259+
})
260+
})
261+
234262
describe('createFolders', () => {
235263
beforeEach(() => {
236264
jest.resetAllMocks()
265+
jest.spyOn(fs, 'existsSync')
266+
jest.spyOn(fs, 'rmSync')
237267
jest.spyOn(fs, 'mkdirSync')
238268
jest.spyOn(logger, 'debug')
239269
})
240270

241-
it('should create all specified folders', () => {
271+
it('should clean and create all specified folders', () => {
272+
fs.existsSync.mockReturnValue(true)
273+
createFolders('/config', '/shared', '/results')
274+
// Verify folders are cleaned first
275+
expect(fs.rmSync).toHaveBeenCalledWith('/config', {
276+
recursive: true,
277+
force: true
278+
})
279+
expect(fs.rmSync).toHaveBeenCalledWith('/shared', {
280+
recursive: true,
281+
force: true
282+
})
283+
// Verify folders are created
284+
expect(fs.mkdirSync).toHaveBeenCalledWith('/config', { recursive: true })
285+
expect(fs.mkdirSync).toHaveBeenCalledWith('/shared', { recursive: true })
286+
expect(fs.mkdirSync).toHaveBeenCalledWith('/results', { recursive: true })
287+
})
288+
289+
it('should create folders even if they do not exist (no cleanup needed)', () => {
290+
fs.existsSync.mockReturnValue(false)
242291
createFolders('/config', '/shared', '/results')
292+
// Verify no cleanup attempted
293+
expect(fs.rmSync).not.toHaveBeenCalled()
294+
// Verify folders are created
243295
expect(fs.mkdirSync).toHaveBeenCalledWith('/config', { recursive: true })
244296
expect(fs.mkdirSync).toHaveBeenCalledWith('/shared', { recursive: true })
245297
expect(fs.mkdirSync).toHaveBeenCalledWith('/results', { recursive: true })

__tests__/util/insta-infra.test.js

Lines changed: 83 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
const {
22
checkInstaInfraExists,
3-
runServices
3+
runServices,
4+
shutdownServices
45
} = require('../../src/util/insta-infra')
5-
const fs = require('fs')
66
const { execSync } = require('child_process')
77
const logger = require('../../src/util/log')
88
const { isContainerFinished } = require('../../src/util/docker')
@@ -12,69 +12,65 @@ jest.mock('../../src/util/log')
1212
jest.mock('../../src/util/docker')
1313

1414
describe('checkInstaInfraExists', () => {
15-
it('should clone repository if insta-infra folder does not exist', () => {
16-
jest.spyOn(fs, 'existsSync').mockReturnValue(false)
17-
execSync.mockReturnValueOnce('success')
18-
checkInstaInfraExists('/path/to/insta-infra')
19-
expect(execSync).toHaveBeenCalledWith(
20-
'git clone git@github.com:data-catering/insta-infra.git /path/to/insta-infra'
21-
)
15+
beforeEach(() => {
16+
jest.resetAllMocks()
17+
})
18+
19+
it('should not install if insta CLI is already installed', () => {
20+
execSync.mockReturnValueOnce('/usr/local/bin/insta')
21+
checkInstaInfraExists()
22+
expect(execSync).toHaveBeenCalledWith('which insta', {
23+
encoding: 'utf-8',
24+
stdio: 'pipe'
25+
})
26+
expect(execSync).toHaveBeenCalledTimes(1)
2227
})
2328

24-
it('should log error and retry with https if git clone via ssh fails', () => {
25-
jest.spyOn(fs, 'existsSync').mockReturnValue(false)
29+
it('should install insta CLI if not found', () => {
2630
execSync.mockImplementationOnce(() => {
27-
throw new Error('ssh failed')
31+
throw new Error('not found')
2832
})
2933
execSync.mockReturnValueOnce('success')
30-
checkInstaInfraExists('/path/to/insta-infra')
34+
checkInstaInfraExists()
3135
expect(execSync).toHaveBeenCalledWith(
32-
'git clone https://github.com/data-catering/insta-infra.git /path/to/insta-infra'
36+
'curl -fsSL https://raw.githubusercontent.com/data-catering/insta-infra/main/install.sh | sh',
37+
{ stdio: 'pipe' }
3338
)
3439
})
3540

36-
it('should throw error if both git clone via ssh and https fail', () => {
37-
jest.spyOn(fs, 'existsSync').mockReturnValue(false)
41+
it('should throw error if installation fails', () => {
3842
execSync.mockImplementationOnce(() => {
39-
throw new Error('ssh failed')
43+
throw new Error('not found')
4044
})
4145
execSync.mockImplementationOnce(() => {
42-
throw new Error('https failed')
46+
throw new Error('install failed')
4347
})
44-
expect(() => checkInstaInfraExists('/path/to/insta-infra')).toThrow(
45-
'Failed to checkout insta-infra repository'
48+
expect(() => checkInstaInfraExists()).toThrow(
49+
'Failed to install insta CLI. Please install manually: https://github.com/data-catering/insta-infra'
4650
)
4751
})
48-
49-
it('should not clone repository if insta-infra folder exists', () => {
50-
jest.spyOn(fs, 'existsSync').mockReturnValue(true)
51-
checkInstaInfraExists('/path/to/insta-infra')
52-
expect(execSync).not.toHaveBeenCalled()
53-
})
5452
})
5553

5654
describe('runServices', () => {
57-
it('should run services successfully', () => {
55+
beforeEach(() => {
56+
jest.resetAllMocks()
57+
})
58+
59+
it('should run services successfully without persistence flag', () => {
5860
execSync.mockReturnValueOnce('service1 service2')
5961
execSync.mockReturnValueOnce('success')
60-
runServices('/path/to/insta-infra', ['service1', 'service2'], {
61-
ENV_VAR: 'value'
62-
})
63-
expect(execSync).toHaveBeenCalledWith('./run.sh service1 service2', {
64-
cwd: '/path/to/insta-infra',
62+
runServices(['service1', 'service2'], { ENV_VAR: 'value' })
63+
// Verify services are started WITHOUT -p flag (no data persistence)
64+
expect(execSync).toHaveBeenCalledWith('insta service1 service2', {
6565
stdio: 'pipe'
6666
})
6767
})
6868

6969
it('should throw error if unsupported service is found', () => {
7070
execSync.mockReturnValueOnce('service1\nservice2')
71-
expect(() =>
72-
runServices(
73-
'/path/to/insta-infra',
74-
['service1', 'unsupportedService'],
75-
{}
76-
)
77-
).toThrow('Unsupported service: unsupportedService')
71+
expect(() => runServices(['service1', 'unsupportedService'], {})).toThrow(
72+
'Unsupported service: unsupportedService'
73+
)
7874
})
7975

8076
it('should log error and check container status if running services fail', () => {
@@ -83,9 +79,7 @@ describe('runServices', () => {
8379
throw new Error('run failed')
8480
})
8581
isContainerFinished.mockReturnValueOnce(true)
86-
expect(() => runServices('/path/to/insta-infra', ['service1'], {})).toThrow(
87-
'run failed'
88-
)
82+
expect(() => runServices(['service1'], {})).toThrow('run failed')
8983
expect(logger.logError).toHaveBeenCalledWith(
9084
'[Service]',
9185
'Failed to start services: service1'
@@ -98,17 +92,57 @@ describe('runServices', () => {
9892
throw new Error('run failed')
9993
})
10094
isContainerFinished.mockReturnValue(false)
101-
expect(() =>
102-
runServices(
103-
'/path/to/insta-infra',
104-
['service1', 'service2', 'service3'],
105-
{}
106-
)
107-
).toThrow('run failed')
95+
expect(() => runServices(['service1', 'service2', 'service3'], {})).toThrow(
96+
'run failed'
97+
)
10898
// All three services should be checked
10999
expect(isContainerFinished).toHaveBeenCalledTimes(3)
110100
expect(isContainerFinished).toHaveBeenCalledWith('service1')
111101
expect(isContainerFinished).toHaveBeenCalledWith('service2')
112102
expect(isContainerFinished).toHaveBeenCalledWith('service3')
113103
})
104+
105+
it('should set environment variables before starting services', () => {
106+
execSync.mockReturnValueOnce('postgres')
107+
execSync.mockReturnValueOnce('success')
108+
const envVars = { POSTGRES_USER: 'test', POSTGRES_PASSWORD: 'secret' }
109+
runServices(['postgres'], envVars)
110+
expect(process.env.POSTGRES_USER).toBe('test')
111+
expect(process.env.POSTGRES_PASSWORD).toBe('secret')
112+
})
113+
})
114+
115+
describe('shutdownServices', () => {
116+
beforeEach(() => {
117+
jest.resetAllMocks()
118+
})
119+
120+
it('should shutdown specific services', () => {
121+
execSync.mockReturnValueOnce('success')
122+
shutdownServices(['postgres', 'mysql'])
123+
expect(execSync).toHaveBeenCalledWith('insta -d postgres mysql', {
124+
stdio: 'pipe'
125+
})
126+
})
127+
128+
it('should shutdown all services when no services specified', () => {
129+
execSync.mockReturnValueOnce('success')
130+
shutdownServices()
131+
expect(execSync).toHaveBeenCalledWith('insta -d', { stdio: 'pipe' })
132+
})
133+
134+
it('should shutdown all services when empty array provided', () => {
135+
execSync.mockReturnValueOnce('success')
136+
shutdownServices([])
137+
expect(execSync).toHaveBeenCalledWith('insta -d', { stdio: 'pipe' })
138+
})
139+
140+
it('should warn but not throw if shutdown fails', () => {
141+
execSync.mockImplementationOnce(() => {
142+
throw new Error('shutdown failed')
143+
})
144+
// Should not throw
145+
expect(() => shutdownServices(['postgres'])).not.toThrow()
146+
expect(logger.warn).toHaveBeenCalled()
147+
})
114148
})

action.yml

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@ inputs:
1010
configuration_file:
1111
description: 'File path to configuration file.'
1212
default: 'insta-integration.yaml'
13-
insta_infra_folder:
14-
description: 'Folder path to insta-infra.'
15-
default: 'integration-test/insta-infra'
1613
base_folder:
1714
description: 'Folder path to use for execution files.'
1815
default: '/home/runner/work'
@@ -44,20 +41,12 @@ outputs:
4441
runs:
4542
using: 'composite'
4643
steps:
47-
- name: 'Checkout insta-infra repo'
48-
uses: 'actions/checkout@v4'
49-
with:
50-
repository: 'data-catering/insta-infra'
51-
path: '${{ inputs.insta_infra_folder }}'
52-
ref: 'v1.0.0'
53-
- name: 'Cache Docker images'
54-
id: 'docker-cache'
55-
uses: 'ScribeMD/docker-cache@0.5.0'
56-
with:
57-
key:
58-
docker-${{ runner.os }}-${{
59-
hashFiles(format('{0}/docker-compose.yaml',
60-
inputs.insta_infra_folder)) }}
44+
- name: 'Install insta CLI'
45+
shell: 'bash'
46+
run:
47+
'curl -fsSL
48+
https://raw.githubusercontent.com/data-catering/insta-infra/main/install.sh
49+
| sh'
6150
- uses: 'actions/setup-node@v4'
6251
with:
6352
node-version: '20.x'
@@ -68,7 +57,5 @@ runs:
6857
env:
6958
CONFIGURATION_FILE:
7059
'${{ github.workspace }}/${{ inputs.configuration_file }}'
71-
INSTA_INFRA_FOLDER:
72-
'${{ github.workspace }}/${{ inputs.insta_infra_folder }}'
7360
BASE_FOLDER: '${{ github.workspace }}'
7461
DATA_CATERER_VERSION: '${{ inputs.data_caterer_version }}'

0 commit comments

Comments
 (0)