Skip to content

Commit

Permalink
Merge pull request #110 from dmvict/keep_env
Browse files Browse the repository at this point in the history
READY: Handle multiple commands in the same environment
  • Loading branch information
dmvict authored Sep 19, 2023
2 parents de48941 + 59244ed commit 29598f1
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 17 deletions.
6 changes: 3 additions & 3 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Works with either shell commands or other actions to retry.

## Why

Github actions which use an Internet connection can fail when connection is lost :
Github actions which use Internet connection can fail when connection is lost :

```bash
Run actions/setup-node@v1
Expand All @@ -25,7 +25,7 @@ It is a cause of failed jobs. For this case, the action `wretry.action` can retr

- Retries Github `JavaScript` actions. The action can be an action repository that is not published on `Marketplace`.
- Retries Github `Docker` actions which use `Dockerfile` as image.
- Retries shell commands.
- Retries shell commands. Uses default shells to run commands.
- Can retry single action or single command ( multiline command ), but not both simultaneously.
- Retries `main`, `pre` and `post` stages of external actions.
- Always has `pre` and `post` stages. If external action has `pre` or/and `post` stage, then action run it also.
Expand All @@ -42,7 +42,7 @@ The name of the Github action.

### `command`

The command to run.
The command to run. The executor uses only the default Github shell. To run alternative shells, wrap the script.

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

Expand Down
13 changes: 12 additions & 1 deletion src/Retry.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,28 @@ function retry( scriptType )
if( !actionName )
{
const commands = common.commandsForm( command );
if( process.platform === 'win32' )
{
commands.push( 'if ((Test-Path -LiteralPath variable:\LASTEXITCODE)) { exit $LASTEXITCODE }' );
commands.unshift( `$ErrorActionPreference = 'stop'` );
}
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 );
let execPath =
process.platform === 'win32' ?
`pwsh -command ". '${ _.path.nativize( commandsScriptPath ) }'"` :
`bash --noprofile --norc -eo pipefail ${ _.path.nativize( commandsScriptPath ) }`;

routine = () =>
{
const o =
{
currentPath,
execPath : commands,
execPath,
inputMirroring : 0,
stdio : 'inherit',
mode : 'shell',
Expand Down
101 changes: 88 additions & 13 deletions test/Command.test.s
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ function retryWithoutCommand( test )

//

function retryWithWrongComand( test )
function retryWithWrongCommand( test )
{
let context = this;
const a = test.assetFor( false );
Expand All @@ -125,7 +125,10 @@ function retryWithWrongComand( test )
test.notIdentical( op.exitCode, 0 );
test.identical( _.strCount( op.output, '::error::Please, specify Github action name' ), 0 );
test.identical( _.strCount( op.output, '::error::Process returned exit code' ), 1 );
test.identical( _.strCount( op.output, 'Launched as "wrong command"' ), 1 );
if( process.platform === 'win32' )
test.identical( _.strCount( op.output, /Launched as \"pwsh .*\"/ ), 1 );
else
test.identical( _.strCount( op.output, /Launched as \"bash .*\"/ ), 1 );
test.identical( _.strCount( op.output, 'Attempts exhausted, made 4 attempts' ), 1 );
return null;
});
Expand Down Expand Up @@ -159,9 +162,11 @@ function retryWithWrongComand( test )
}
}

retryWithWrongCommand.timeOut = 120000;

//

function retryWithValidComand( test )
function retryWithValidCommand( test )
{
let context = this;
const a = test.assetFor( false );
Expand Down Expand Up @@ -227,13 +232,13 @@ function retryWithOptionCurrentPath( test )
const a = test.assetFor( false );
const actionPath = a.abs( '_action/actions/wretry.action/v1' );
const execPath = `node ${ a.path.nativize( a.abs( actionPath, 'src/Main.js' ) ) }`;
const command = process.platform === 'win32' ? 'Get-Location' : 'echo $PWD'

/* - */

a.ready.then( () =>
{
test.case = 'without action name';
const command = process.platform === 'win32' ? 'chdir' : 'echo $PWD'
test.case = 'without current path';
core.exportVariable( `INPUT_COMMAND`, command );
core.exportVariable( `INPUT_ATTEMPT_LIMIT`, '4' );
return null;
Expand All @@ -247,6 +252,7 @@ function retryWithOptionCurrentPath( test )
test.identical( op.exitCode, 0 );
test.identical( _.strCount( op.output, '::error::Please, specify Github action name' ), 0 );
test.identical( _.strCount( op.output, 'Attempts exhausted, made 4 attempts' ), 0 );
if( process.platform !== 'win32' )
test.identical( _.strCount( op.output, a.path.nativize( actionPath ) ), 1 );
return null;
});
Expand All @@ -255,10 +261,9 @@ function retryWithOptionCurrentPath( test )

a.ready.then( () =>
{
test.case = 'without action name';
const command = process.platform === 'win32' ? 'chdir' : 'echo $PWD'
test.case = 'without current path';
core.exportVariable( `INPUT_COMMAND`, command );
core.exportVariable( `INPUT_CURRENT_PATH`, '..' );
core.exportVariable( `INPUT_CURRENT_PATH`, '../../..' );
core.exportVariable( `INPUT_ATTEMPT_LIMIT`, '4' );
return null;
});
Expand All @@ -271,7 +276,7 @@ function retryWithOptionCurrentPath( test )
test.identical( op.exitCode, 0 );
test.identical( _.strCount( op.output, '::error::Please, specify Github action name' ), 0 );
test.identical( _.strCount( op.output, 'Attempts exhausted, made 4 attempts' ), 0 );
test.identical( _.strCount( op.output, a.path.nativize( a.abs( actionPath, '..' ) ) ), 1 );
test.identical( _.strCount( op.output, a.path.nativize( a.abs( actionPath, '../../..' ) ) ), 1 );
return null;
});

Expand Down Expand Up @@ -306,7 +311,7 @@ function retryWithOptionCurrentPath( test )

//

function retryWithMultilineComand( test )
function retryWithMultilineCommand( test )
{
let context = this;

Expand All @@ -322,6 +327,9 @@ function retryWithMultilineComand( test )
a.ready.then( () =>
{
test.case = 'multiline command';
if( process.platform === 'win32' )
core.exportVariable( `INPUT_COMMAND`, '|\n echo `\n str' );
else
core.exportVariable( `INPUT_COMMAND`, '|\n echo \\\n str' );
core.exportVariable( `INPUT_ATTEMPT_LIMIT`, '4' );
return null;
Expand All @@ -344,6 +352,9 @@ function retryWithMultilineComand( test )
a.ready.then( () =>
{
test.case = 'several multiline command';
if( process.platform === 'win32' )
core.exportVariable( `INPUT_COMMAND`, '|\n echo `\n str\n echo `\n bar' );
else
core.exportVariable( `INPUT_COMMAND`, '|\n echo \\\n str\n echo \\\n bar' );
core.exportVariable( `INPUT_ATTEMPT_LIMIT`, '4' );
return null;
Expand Down Expand Up @@ -391,6 +402,69 @@ function retryWithMultilineComand( test )
}
}

//

function retryAndCheckRuntimeEnvironments( test )
{
let context = this;
const a = test.assetFor( false );
const actionPath = a.abs( '_action/actions/wretry.action/v1' );
const execPath = `node ${ a.path.nativize( a.abs( actionPath, 'src/Main.js' ) ) }`;

/* - */

a.ready.then( () =>
{
test.case = 'multiline command';
if( process.platform === 'win32' )
core.exportVariable( `INPUT_COMMAND`, '|\n $FOO="foo" \n $BAR="bar" \n echo $FOO$BAR' );
else
core.exportVariable( `INPUT_COMMAND`, '|\n export FOO=foo \n export BAR=bar \n echo $FOO$BAR' );
core.exportVariable( `INPUT_ATTEMPT_LIMIT`, '4' );
return null;
});

actionSetup();

a.shellNonThrowing({ currentPath : actionPath, execPath });
a.ready.then( ( op ) =>
{
test.identical( op.exitCode, 0 );
test.identical( _.strCount( op.output, '::error::Please, specify Github action name' ), 0 );
test.identical( _.strCount( op.output, 'Attempts exhausted, made 4 attempts' ), 0 );
test.identical( _.strCount( op.output, 'foobar' ), 1 );
return null;
});

/* - */

return a.ready;

/* */

function actionSetup()
{
a.ready.then( () =>
{
a.fileProvider.filesDelete( a.abs( '.' ) );
a.fileProvider.dirMake( actionPath );
return null;
});
a.ready.then( () =>
{
return __.git.repositoryClone
({
localPath : actionPath,
remotePath : __.git.path.normalize( context.actionDirPath ),
attemptLimit : 4,
attemptDelay : 250,
attemptDelayMultiplier : 4,
});
});
return a.ready;
}
}

// --
// declare
// --
Expand All @@ -413,10 +487,11 @@ const Proto =
tests :
{
retryWithoutCommand,
retryWithWrongComand,
retryWithValidComand,
retryWithWrongCommand,
retryWithValidCommand,
retryWithOptionCurrentPath,
retryWithMultilineComand,
retryWithMultilineCommand,
retryAndCheckRuntimeEnvironments,
},
};

Expand Down

0 comments on commit 29598f1

Please sign in to comment.