Skip to content

Commit

Permalink
Merge pull request #169 from dmvict/js_action
Browse files Browse the repository at this point in the history
READY:  Add pre retry command
  • Loading branch information
dmvict authored Oct 29, 2024
2 parents 9660582 + ac8cdbf commit b137cfa
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 32 deletions.
4 changes: 4 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ The command to run. The action runs the command in the default shell.

**Attention**. Action requires defined `action` or `command`. If the fields `action` and `commands` are defined simultaneously, then action will throw error.

### `pre_retry_command`

Command to run between retries.

### `with`

An options map for Github action. It is a multiline string with pairs `key : value`.
Expand Down
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ inputs:
command:
description: 'Command to run. Should be defined action or command, not both.'
required: false
pre_retry_command:
description: 'Command to run between retries.'
required: false
with:
description: 'An options map for Github action'
required: false
Expand Down

This file was deleted.

105 changes: 74 additions & 31 deletions src/Retry.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,43 +8,42 @@ const _ = wTools;
function retry( scriptType )
{
let shouldRetry = core.getInput( 'retry_condition' ) || true;
const actionName = core.getInput( 'action' );
const command = core.getMultilineInput( 'command' );
const preRetryCommand = core.getMultilineInput( 'pre_retry_command' );

let currentPath = core.getInput( 'current_path' ) || _.path.current();
if( !_.path.isAbsolute( currentPath ) )
currentPath = _.path.join( _.path.current(), currentPath );

let preRetryExecPath = null;
if( preRetryCommand.length > 0 )
preRetryExecPath = execPathFromCommandAndNameForm( preRetryCommand, 'pre_script' );

let startTime = null;
const timeLimit = _.number.from( core.getInput( 'time_out' ) ) || null;
let timeoutGet = () => null;
if( timeLimit )
{
startTime = _.time.now();
timeoutGet = () =>
{
let now = _.time.now();
let spent = now - startTime;
if( spent >= timeLimit )
shouldRetry = false;
return timeLimit - spent;
};
}

return _.Consequence.Try( () =>
{
let routine, startTime;
let routine;
const con = _.take( null );
const actionName = core.getInput( 'action' );
const command = core.getMultilineInput( 'command' );

const timeLimit = _.number.from( core.getInput( 'time_out' ) ) || null;
let timeoutGet = () => null;
if( timeLimit )
{
startTime = _.time.now();
timeoutGet = () =>
{
let now = _.time.now();
let spent = now - startTime;
if( spent >= timeLimit )
shouldRetry = false;
return timeLimit - spent;
};
}

if( !actionName )
{
const commands = common.commandsForm( command );
const commandsScriptPath = _.path.join( __dirname, process.platform === 'win32' ? 'script.ps1' : 'script.sh' );
_.fileProvider.fileWrite( commandsScriptPath, commands.join( '\n' ) );

let currentPath = core.getInput( 'current_path' ) || _.path.current();
if( !_.path.isAbsolute( currentPath ) )
currentPath = _.path.join( _.path.current(), currentPath );
const execPath =
process.platform === 'win32' ?
`pwsh -command ". '${ _.path.nativize( commandsScriptPath ) }'"` :
`bash --noprofile --norc -eo pipefail ${ _.path.nativize( commandsScriptPath ) }`;

const execPath = execPathFromCommandAndNameForm( command, 'script' );
routine = () =>
{
const o =
Expand Down Expand Up @@ -167,8 +166,37 @@ function retry( scriptType )
{
if( process.env.GITHUB_OUTPUT && _.fileProvider.fileExists( process.env.GITHUB_OUTPUT ) )
_.fileProvider.fileWrite( process.env.GITHUB_OUTPUT, '' );
return routine();

if( preRetryCommand.length > 0 )
{
const o =
{
currentPath,
execPath : preRetryExecPath,
inputMirroring : 0,
stdio : 'inherit',
mode : 'shell',
};
o.timeOut = timeoutGet();
_.process.start( o );

return o.ready.catch( ( err ) =>
{
_.error.attend( err );
shouldRetry = false;
return err;
})
.then( () =>
{
return routine();
});
}
else
{
return routine();
}
};

return _.retry
({
routine : githubOutputCleanRoutine,
Expand Down Expand Up @@ -201,10 +229,25 @@ function retry( scriptType )
function onError( err )
{
_.error.attend( err );

if( _.bool.is( shouldRetry ) )
return shouldRetry;
return !!common.evaluateExpression( shouldRetry );
}

function execPathFromCommandAndNameForm( command, scriptName )
{

const commands = common.commandsForm( command );
const commandsScriptPath = _.path.join( __dirname, process.platform === 'win32' ? `${ scriptName }.ps1` : `${ scriptName }.sh` );
_.fileProvider.fileWrite( commandsScriptPath, commands.join( '\n' ) );

const execPath = process.platform === 'win32' ?
`pwsh -command ". '${ _.path.nativize( commandsScriptPath ) }'"` :
`bash --noprofile --norc -eo pipefail ${ _.path.nativize( commandsScriptPath ) }`;

return execPath;
}
}

module.exports = { retry };
Expand Down
88 changes: 88 additions & 0 deletions test/Action.test.s
Original file line number Diff line number Diff line change
Expand Up @@ -885,6 +885,93 @@ function retryWithOptionRetryCondition( test )

//

function retryWithOptionPreRetryCommand( test )
{
const context = this;
const a = test.assetFor( false );
const actionPath = a.abs( '_action/actions/wretry.action/v1' );
const testAction = 'dmvict/[email protected]';
const execPath = `node ${ a.path.nativize( a.abs( actionPath, 'src/Main.js' ) ) }`;
const isTestContainer = _.process.insideTestContainer();

/* - */

a.ready.then( () =>
{
test.case = 'enought attempts, executing command between retries';
core.exportVariable( `INPUT_ACTION`, testAction );
core.exportVariable( `INPUT_WITH`, 'value : 0' );
core.exportVariable( `INPUT_ATTEMPT_LIMIT`, '4' );
core.exportVariable( `INPUT_PRE_RETRY_COMMAND`, 'echo "Executing pre_retry_command"' );
return null;
});

actionSetup();

a.shellNonThrowing({ currentPath : actionPath, execPath });
a.ready.then( ( op ) =>
{
test.identical( op.exitCode, 0 );
if( !isTestContainer )
test.ge( _.strCount( op.output, '::set-env' ), 3 );
test.identical( _.strCount( op.output, '::error::Wrong attempt' ), 3 );
test.identical( _.strCount( op.output, /::error::undefined.*Attempts exhausted, made 4 attempts/ ), 0 );
test.identical( _.strCount( op.output, /::error::.*Process returned exit code/ ), 0 );
test.identical( _.strCount( op.output, 'Success' ), 1 );
test.identical( _.strCount( op.output, 'Executing pre_retry_command' ), 4 );
return null;
});

/* */

a.ready.then( () =>
{
test.case = 'command between retries trows error, interrupting execution';
core.exportVariable( `INPUT_ACTION`, testAction );
core.exportVariable( `INPUT_WITH`, 'value : 0' );
core.exportVariable( `INPUT_ATTEMPT_LIMIT`, '4' );
core.exportVariable( `INPUT_PRE_RETRY_COMMAND`, 'exit 1' );
return null;
});

actionSetup();

a.shellNonThrowing({ currentPath : actionPath, execPath });
a.ready.then( ( op ) =>
{
test.notIdentical( op.exitCode, 0 );
if( !isTestContainer )
test.ge( _.strCount( op.output, '::set-env' ), 2 );
test.identical( _.strCount( op.output, '::error::Wrong attempt' ), 1 );
test.identical( _.strCount( op.output, /::error::undefined.*Attempts exhausted, made 4 attempts/ ), 0 );
test.identical( _.strCount( op.output, /::error::.*Process returned exit code/ ), 1 );
test.identical( _.strCount( op.output, 'Success' ), 0 );
return null;
});

a.ready.finally( () =>
{
delete process.env.INPUT_PRE_RETRY_COMMAND;
return null;
});

/* - */

return a.ready;

/* */

function actionSetup()
{
a.ready.then( () => { a.fileProvider.filesDelete( a.abs( '.' ) ); return null; } );
a.ready.then( () => { a.fileProvider.dirMake( actionPath ); return null; } );
a.shell( `git clone ${ a.path.nativize( context.actionDirPath ) } ${ a.path.nativize( actionPath ) }` );
return a.ready;
}
}

//

function retryWithExternalActionOnLocal( test )
{
const context = this;
Expand Down Expand Up @@ -1869,6 +1956,7 @@ const Proto =
retryWithOptionAttemptLimit,
retryWithOptionAttemptDelay,
retryWithOptionRetryCondition,
retryWithOptionPreRetryCommand,

retryWithExternalActionOnLocal,
retryWithExternalActionOnRemote,
Expand Down

0 comments on commit b137cfa

Please sign in to comment.