From b71ad7535207f2e7e37c01f076725f98a5f37df9 Mon Sep 17 00:00:00 2001 From: James Ives Date: Fri, 26 Jun 2020 08:18:23 -0400 Subject: [PATCH] Silent Settings (#347) --- README.md | 3 +- __tests__/execute.test.ts | 8 ++-- __tests__/git.test.ts | 22 +++++++++ src/constants.ts | 5 +++ src/execute.ts | 10 +++-- src/git.ts | 95 ++++++++++++++++++++++++++++----------- 6 files changed, 108 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 2f2b85ed..caa225a0 100644 --- a/README.md +++ b/README.md @@ -147,6 +147,7 @@ In addition to the deployment options you must also configure the following. | `CLEAN` | If your project generates hashed files on build you can use this option to automatically delete them from the deployment branch with each deploy. This option can be toggled on by setting it to `true`. | `with` | **No** | | `CLEAN_EXCLUDE` | If you need to use `CLEAN` but you'd like to preserve certain files or folders you can use this option. This should be formatted as an array but stored as a string. For example: `'["filename.js", "folder"]'` | `with` | **No** | | `SINGLE_COMMIT` | This option can be toggled to `true` if you'd prefer to have a single commit on the deployment branch instead of maintaining the full history. **Using this option will also cause any existing history to be wiped from the deployment branch**. | `with` | **No** | +| `SILENT` | Silences the action output preventing it from displaying git messages and error. | `with` | **No** | | `WORKSPACE` | This should point to where your project lives on the virtual machine. The GitHub Actions environment will set this for you. It is only neccersary to set this variable if you're using the node module. | `with` | **No** | With the action correctly configured you should see the workflow trigger the deployment under the configured conditions. @@ -320,4 +321,4 @@ If you're using a custom domain and require a `CNAME` file, or if you require th ### Debugging 🐝 -By default the git commands are hidden from the logs. If you'd like to turn them on you can set the `ACTIONS_STEP_DEBUG` environment variable to true within the [Settings/Secrets](https://help.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets#creating-encrypted-secrets) menu. If you're using this action in your own project as a node module via yarn or npm **you may expose your secrets if you toggle this on in a production environment**. You can learn more about debugging GitHub actions [here](https://github.com/actions/toolkit/blob/master/docs/action-debugging.md). +If you'd like to enable action debugging you can set the `ACTIONS_STEP_DEBUG` environment variable to true within the [Settings/Secrets](https://help.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets#creating-encrypted-secrets) menu. If you're using this action in your own project as a node module via yarn or npm **you may expose your secrets if you toggle this on in a production environment**. You can learn more about debugging GitHub actions [here](https://github.com/actions/toolkit/blob/master/docs/action-debugging.md). diff --git a/__tests__/execute.test.ts b/__tests__/execute.test.ts index 3999736b..14831ba8 100644 --- a/__tests__/execute.test.ts +++ b/__tests__/execute.test.ts @@ -6,9 +6,9 @@ jest.mock('@actions/exec', () => ({ })) describe('execute', () => { - it('should be called with the correct arguments', async () => { + it('should be called with the correct arguments when silent mode is enabled', async () => { stdout('hello') - await execute('echo Montezuma', './') + await execute('echo Montezuma', './', true) expect(exec).toBeCalledWith('echo Montezuma', [], { cwd: './', @@ -19,11 +19,11 @@ describe('execute', () => { }) }) - it('should not silence the input when INPUT_DEBUG is defined', async () => { + it('should not silence the input when action.silent is false', async () => { process.env['RUNNER_DEBUG'] = '1' stdout('hello') - await execute('echo Montezuma', './') + await execute('echo Montezuma', './', false) expect(exec).toBeCalledWith('echo Montezuma', [], { cwd: './', diff --git a/__tests__/git.test.ts b/__tests__/git.test.ts index 87381633..879620fd 100644 --- a/__tests__/git.test.ts +++ b/__tests__/git.test.ts @@ -33,6 +33,7 @@ describe('git', () => { describe('init', () => { it('should execute commands if a GitHub token is provided', async () => { Object.assign(action, { + silent: false, repositoryPath: 'JamesIves/github-pages-deploy-action', folder: 'assets', branch: 'branch', @@ -49,6 +50,7 @@ describe('git', () => { it('should execute commands if an Access Token is provided', async () => { Object.assign(action, { + silent: false, repositoryPath: 'JamesIves/github-pages-deploy-action', folder: 'assets', branch: 'branch', @@ -65,6 +67,7 @@ describe('git', () => { it('should execute commands if SSH is true', async () => { Object.assign(action, { + silent: false, repositoryPath: 'JamesIves/github-pages-deploy-action', folder: 'assets', branch: 'branch', @@ -82,6 +85,7 @@ describe('git', () => { it('should fail if there is no provided GitHub Token, Access Token or SSH bool', async () => { Object.assign(action, { + silent: false, repositoryPath: null, folder: 'assets', branch: 'branch', @@ -103,6 +107,7 @@ describe('git', () => { it('should fail if access token is defined but it is an empty string', async () => { Object.assign(action, { + silent: false, repositoryPath: null, folder: 'assets', branch: 'branch', @@ -125,6 +130,7 @@ describe('git', () => { it('should fail if there is no folder', async () => { Object.assign(action, { + silent: false, repositoryPath: 'JamesIves/github-pages-deploy-action', gitHubToken: '123', branch: 'branch', @@ -148,6 +154,7 @@ describe('git', () => { it('should fail if there is no provided repository path', async () => { Object.assign(action, { + silent: true, repositoryPath: null, folder: 'assets', branch: 'branch', @@ -172,6 +179,7 @@ describe('git', () => { it('should fail if the build folder begins with a /', async () => { Object.assign(action, { + silent: false, accessToken: '123', repositoryPath: 'JamesIves/github-pages-deploy-action', branch: 'branch', @@ -194,6 +202,7 @@ describe('git', () => { it('should fail if the build folder begins with a ./', async () => { Object.assign(action, { + silent: false, accessToken: '123', branch: 'branch', folder: './', @@ -215,6 +224,7 @@ describe('git', () => { it('should not fail if root is used', async () => { Object.assign(action, { + silent: false, repositoryPath: 'JamesIves/github-pages-deploy-action', accessToken: '123', branch: 'branch', @@ -235,6 +245,7 @@ describe('git', () => { describe('generateBranch', () => { it('should execute six commands', async () => { Object.assign(action, { + silent: false, accessToken: '123', branch: 'branch', folder: '.', @@ -250,6 +261,7 @@ describe('git', () => { it('should fail if there is no branch', async () => { Object.assign(action, { + silent: false, accessToken: '123', branch: null, folder: '.', @@ -272,6 +284,7 @@ describe('git', () => { describe('switchToBaseBranch', () => { it('should execute one command', async () => { Object.assign(action, { + silent: false, accessToken: '123', branch: 'branch', folder: '.', @@ -287,6 +300,7 @@ describe('git', () => { it('should execute one command if using custom baseBranch', async () => { Object.assign(action, { + silent: false, baseBranch: '123', accessToken: '123', branch: 'branch', @@ -303,6 +317,7 @@ describe('git', () => { it('should fail if one of the required parameters is not available', async () => { Object.assign(action, { + silent: false, baseBranch: '123', accessToken: null, gitHubToken: null, @@ -329,6 +344,7 @@ describe('git', () => { describe('deploy', () => { it('should execute commands', async () => { Object.assign(action, { + silent: false, folder: 'assets', branch: 'branch', gitHubToken: '123', @@ -348,6 +364,7 @@ describe('git', () => { it('should execute commands with single commit toggled', async () => { Object.assign(action, { + silent: false, folder: 'assets', branch: 'branch', gitHubToken: '123', @@ -368,6 +385,7 @@ describe('git', () => { it('should execute commands with clean options, ommits sha commit message', async () => { process.env.GITHUB_SHA = '' Object.assign(action, { + silent: false, folder: 'assets', branch: 'branch', gitHubToken: '123', @@ -388,6 +406,7 @@ describe('git', () => { it('should execute commands with clean options stored as an array instead', async () => { Object.assign(action, { + silent: false, folder: 'assets', branch: 'branch', gitHubToken: '123', @@ -408,6 +427,7 @@ describe('git', () => { it('should gracefully handle incorrectly formatted clean exclude items', async () => { Object.assign(action, { + silent: false, folder: '.', branch: 'branch', gitHubToken: '123', @@ -428,6 +448,7 @@ describe('git', () => { it('should stop early if there is nothing to commit', async () => { Object.assign(action, { + silent: false, folder: 'assets', branch: 'branch', gitHubToken: '123', @@ -446,6 +467,7 @@ describe('git', () => { it('should throw an error if one of the required parameters is not available', async () => { Object.assign(action, { + silent: false, folder: 'assets', branch: 'branch', ssh: null, diff --git a/src/constants.ts b/src/constants.ts index a2a89ac8..b9b4f832 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -38,6 +38,8 @@ export interface ActionInterface { root?: string /** Wipes the commit history from the deployment branch in favor of a single commit. */ singleCommit?: boolean | null + /** Determines if the action should run in silent mode or not. */ + silent?: boolean /** Set to true if you're using an ssh client in your build step. */ ssh?: boolean | null /** If you'd like to push the contents of the deployment folder into a specific directory on the deployment branch you can specify it here. */ @@ -87,6 +89,9 @@ export const action: ActionInterface = { singleCommit: !isNullOrUndefined(getInput('SINGLE_COMMIT')) ? getInput('SINGLE_COMMIT').toLowerCase() === 'true' : false, + silent: !isNullOrUndefined(getInput('SILENT')) + ? getInput('SILENT').toLowerCase() === 'true' + : false, ssh: !isNullOrUndefined(getInput('SSH')) ? getInput('SSH').toLowerCase() === 'true' : false, diff --git a/src/execute.ts b/src/execute.ts index 51307e2d..9cbcb839 100644 --- a/src/execute.ts +++ b/src/execute.ts @@ -1,4 +1,3 @@ -import {isDebug} from '@actions/core' import {exec} from '@actions/exec' let output: string @@ -8,13 +7,18 @@ let output: string * * @param {string} cmd - The command to execute. * @param {string} cwd - The current working directory. + * @param {boolean} silent - Determines if the in/out should be silenced or not. */ -export async function execute(cmd: string, cwd: string): Promise { +export async function execute( + cmd: string, + cwd: string, + silent?: boolean +): Promise { output = '' await exec(cmd, [], { // Silences the input unless the INPUT_DEBUG flag is set. - silent: isDebug() ? false : true, + silent, cwd, listeners: { stdout diff --git a/src/git.ts b/src/git.ts index fde9eee2..09c09fe1 100644 --- a/src/git.ts +++ b/src/git.ts @@ -16,15 +16,27 @@ export async function init(action: ActionInterface): Promise { info(`Deploying using ${action.tokenType}… 🔑`) info('Configuring git…') - await execute(`git init`, action.workspace) - await execute(`git config user.name "${action.name}"`, action.workspace) - await execute(`git config user.email "${action.email}"`, action.workspace) - await execute(`git remote rm origin`, action.workspace) + await execute(`git init`, action.workspace, action.silent) + await execute( + `git config user.name "${action.name}"`, + action.workspace, + action.silent + ) + await execute( + `git config user.email "${action.email}"`, + action.workspace, + action.silent + ) + await execute(`git remote rm origin`, action.workspace, action.silent) await execute( `git remote add origin ${action.repositoryPath}`, action.workspace ) - await execute(`git fetch --no-recurse-submodules`, action.workspace) + await execute( + `git fetch --no-recurse-submodules`, + action.workspace, + action.silent + ) info('Git configured… 🔧') } catch (error) { @@ -48,7 +60,8 @@ export async function switchToBaseBranch( `git checkout --progress --force ${ action.baseBranch ? action.baseBranch : action.defaultBranch }`, - action.workspace + action.workspace, + action.silent ) } catch (error) { throw new Error( @@ -68,17 +81,23 @@ export async function generateBranch(action: ActionInterface): Promise { info(`Creating the ${action.branch} branch…`) await switchToBaseBranch(action) - await execute(`git checkout --orphan ${action.branch}`, action.workspace) - await execute(`git reset --hard`, action.workspace) + await execute( + `git checkout --orphan ${action.branch}`, + action.workspace, + action.silent + ) + await execute(`git reset --hard`, action.workspace, action.silent) await execute( `git commit --allow-empty -m "Initial ${action.branch} commit"`, - action.workspace + action.workspace, + action.silent ) await execute( `git push --force ${action.repositoryPath} ${action.branch}`, - action.workspace + action.workspace, + action.silent ) - await execute(`git fetch`, action.workspace) + await execute(`git fetch`, action.workspace, action.silent) info(`Created the ${action.branch} branch… 🔧`) } catch (error) { @@ -125,10 +144,15 @@ export async function deploy(action: ActionInterface): Promise { // Checks out the base branch to begin the deployment process. await switchToBaseBranch(action) - await execute(`git fetch ${action.repositoryPath}`, action.workspace) + await execute( + `git fetch ${action.repositoryPath}`, + action.workspace, + action.silent + ) await execute( `git worktree add --checkout ${temporaryDeploymentDirectory} origin/${action.branch}`, - action.workspace + action.workspace, + action.silent ) // Ensures that items that need to be excluded from the clean job get parsed. @@ -173,12 +197,14 @@ export async function deploy(action: ActionInterface): Promise { ? `--exclude ${temporaryDeploymentDirectory}` : '' }`, - action.workspace + action.workspace, + action.silent ) const hasFilesToCommit = await execute( `git status --porcelain`, - `${action.workspace}/${temporaryDeploymentDirectory}` + `${action.workspace}/${temporaryDeploymentDirectory}`, + action.silent ) if (!hasFilesToCommit && !action.isTest) { @@ -188,44 +214,57 @@ export async function deploy(action: ActionInterface): Promise { // Commits to GitHub. await execute( `git add --all .`, - `${action.workspace}/${temporaryDeploymentDirectory}` + `${action.workspace}/${temporaryDeploymentDirectory}`, + action.silent ) await execute( `git checkout -b ${temporaryDeploymentBranch}`, - `${action.workspace}/${temporaryDeploymentDirectory}` + `${action.workspace}/${temporaryDeploymentDirectory}`, + action.silent ) await execute( `git commit -m "${commitMessage}" --quiet`, - `${action.workspace}/${temporaryDeploymentDirectory}` + `${action.workspace}/${temporaryDeploymentDirectory}`, + action.silent ) await execute( `git push --force ${action.repositoryPath} ${temporaryDeploymentBranch}:${action.branch}`, - `${action.workspace}/${temporaryDeploymentDirectory}` + `${action.workspace}/${temporaryDeploymentDirectory}`, + action.silent ) info(`Changes committed to the ${action.branch} branch… 📦`) if (action.singleCommit) { - await execute(`git fetch ${action.repositoryPath}`, action.workspace) + await execute( + `git fetch ${action.repositoryPath}`, + action.workspace, + action.silent + ) await execute( `git checkout --orphan ${action.branch}-temp`, - `${action.workspace}/${temporaryDeploymentDirectory}` + `${action.workspace}/${temporaryDeploymentDirectory}`, + action.silent ) await execute( `git add --all .`, - `${action.workspace}/${temporaryDeploymentDirectory}` + `${action.workspace}/${temporaryDeploymentDirectory}`, + action.silent ) await execute( `git commit -m "${commitMessage}" --quiet`, - `${action.workspace}/${temporaryDeploymentDirectory}` + `${action.workspace}/${temporaryDeploymentDirectory}`, + action.silent ) await execute( `git branch -M ${action.branch}-temp ${action.branch}`, - `${action.workspace}/${temporaryDeploymentDirectory}` + `${action.workspace}/${temporaryDeploymentDirectory}`, + action.silent ) await execute( `git push origin ${action.branch} --force`, - `${action.workspace}/${temporaryDeploymentDirectory}` + `${action.workspace}/${temporaryDeploymentDirectory}`, + action.silent ) info('Cleared git history… 🚿') @@ -233,7 +272,8 @@ export async function deploy(action: ActionInterface): Promise { await execute( `git checkout --progress --force ${action.defaultBranch}`, - action.workspace + action.workspace, + action.silent ) return Status.SUCCESS @@ -249,7 +289,8 @@ export async function deploy(action: ActionInterface): Promise { info('Running post deployment cleanup jobs… 🗑️') await execute( `git worktree remove ${temporaryDeploymentDirectory} --force`, - action.workspace + action.workspace, + action.silent ) await rmRF(temporaryDeploymentDirectory) }