Merge branch 'dev' into releases/v3

This commit is contained in:
JamesIves 2020-03-31 08:38:33 -04:00
commit df5a466cbc
22 changed files with 812 additions and 771 deletions

View File

@ -35,7 +35,6 @@
"@typescript-eslint/no-misused-new": "error",
"@typescript-eslint/no-namespace": "error",
"@typescript-eslint/no-non-null-assertion": "warn",
"@typescript-eslint/no-object-literal-type-assertion": "error",
"@typescript-eslint/no-unnecessary-qualifier": "error",
"@typescript-eslint/no-unnecessary-type-assertion": "error",
"@typescript-eslint/no-useless-constructor": "error",
@ -43,7 +42,6 @@
"@typescript-eslint/prefer-for-of": "warn",
"@typescript-eslint/prefer-function-type": "warn",
"@typescript-eslint/prefer-includes": "error",
"@typescript-eslint/prefer-interface": "error",
"@typescript-eslint/prefer-string-starts-ends-with": "error",
"@typescript-eslint/promise-function-async": "error",
"@typescript-eslint/require-array-sort-compare": "error",

View File

@ -19,6 +19,7 @@ jobs:
- name: Install and Test
run: |
npm install
npm run-script lint
npm run-script test
- name: Uploade CodeCov Report

View File

@ -126,7 +126,7 @@ jobs:
BASE_BRANCH: dev
TARGET_FOLDER: montezuma4
# Deploys using the CLEAN option.
# Deploys using the CLEAN and SINGLE_COMMIT option.
integration-clean:
needs: [integration-checkout-v1, integration-checkout-v2, integration-container, integration-ssh, integration-env]
runs-on: ubuntu-latest
@ -144,8 +144,9 @@ jobs:
FOLDER: integration
BASE_BRANCH: dev
CLEAN: true
SINGLE_COMMIT: true
# Deploys to a branch that doesn't exist.
# Deploys to a branch that doesn't exist with SINGLE_COMMIT toggled.
integration-branch-creation:
runs-on: ubuntu-latest
steps:
@ -162,6 +163,7 @@ jobs:
FOLDER: integration
BASE_BRANCH: dev
CLEAN: true
SINGLE_COMMIT: true
- name: Cleanup Generated Branch
uses: dawidd6/action-delete-branch@v2.0.1

View File

@ -127,7 +127,7 @@ jobs:
BASE_BRANCH: dev
TARGET_FOLDER: montezuma4
# Deploys using the CLEAN option.
# Deploys using the CLEAN option with SINGLE_COMMIT toggled.
integration-clean:
needs: [integration-checkout-v1, integration-checkout-v2, integration-container, integration-ssh, integration-env]
runs-on: ubuntu-latest
@ -145,8 +145,9 @@ jobs:
FOLDER: integration
BASE_BRANCH: dev
CLEAN: true
SINGLE_COMMIT: true
# Deploys to a branch that doesn't exist.
# Deploys to a branch that doesn't exist with SINGLE_COMMIT.
integration-branch-creation:
runs-on: ubuntu-latest
steps:
@ -163,6 +164,7 @@ jobs:
FOLDER: integration
BASE_BRANCH: dev
CLEAN: true
SINGLE_COMMIT: true
- name: Cleanup Generated Branch
uses: dawidd6/action-delete-branch@v2.0.1

View File

@ -5,7 +5,7 @@ on:
types: [created]
jobs:
publish-npm:
publish-npm-js:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
@ -26,3 +26,25 @@ jobs:
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.npm_token }}
publish-npm-github:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: dev
- uses: actions/setup-node@v1
with:
node-version: 12
registry-url: 'https://npm.pkg.github.com'
- name: Configure git
run: |
git config user.email "iam@jamesiv.es"
git config user.name "James Ives"
- run: npm install
- run: npm run-script build
- run: npm version patch -m "Release %s"
- run: npm ci
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -1,10 +1,42 @@
# GitHub Pages Deploy Action :rocket:
<p align="center">
<a href="https://github.com/marketplace/actions/deploy-to-github-pages">
<img width="150px" src="./assets/icon.png">
</a>
</p>
[![Build Status](https://github.com/JamesIves/github-pages-deploy-action/workflows/unit-tests/badge.svg)](https://github.com/JamesIves/github-pages-deploy-action/actions) [![Actions Status](https://github.com/JamesIves/github-pages-deploy-action/workflows/integration-tests/badge.svg)](https://github.com/JamesIves/github-pages-deploy-action/actions) [![View Action](https://img.shields.io/badge/action-marketplace-blue.svg?logo=github&color=orange)](https://github.com/marketplace/actions/deploy-to-github-pages) [![Version](https://img.shields.io/github/v/release/JamesIves/github-pages-deploy-action.svg?logo=github)](https://github.com/JamesIves/github-pages-deploy-action/releases) [![Codecov Coverage](https://codecov.io/gh/JamesIves/github-pages-deploy-action/branch/dev/graph/badge.svg)](https://codecov.io/gh/JamesIves/github-pages-deploy-action/branch/dev)
<h1 align="center">
GitHub Pages Deploy Action :rocket:
</h1>
This [GitHub action](https://github.com/features/actions) will handle the deploy process of your project to [GitHub Pages](https://pages.github.com/). It can be configured to upload your production-ready code into any branch you'd like, including `gh-pages` and `docs`.
<p align="center">
<a href="https://github.com/JamesIves/github-pages-deploy-action/actions">
<img src="https://github.com/JamesIves/github-pages-deploy-action/workflows/unit-tests/badge.svg">
</a>
<a href="https://github.com/JamesIves/github-pages-deploy-action/actions">
<img src="https://github.com/JamesIves/github-pages-deploy-action/workflows/integration-tests/badge.svg">
</a>
<a href="https://github.com/marketplace/actions/deploy-to-github-pages">
<img src="https://img.shields.io/badge/action-marketplace-blue.svg?logo=github&color=orange">
</a>
<a href="https://github.com/JamesIves/github-pages-deploy-action/releases">
<img src="https://img.shields.io/github/v/release/JamesIves/github-pages-deploy-action.svg?logo=github">
</a>
<a href="https://codecov.io/gh/JamesIves/github-pages-deploy-action/branch/dev">
<img src="https://codecov.io/gh/JamesIves/github-pages-deploy-action/branch/dev/graph/badge.svg">
</a>
</p>
![Example Screen shot](screenshot.png)
<p align="center">
This <a href="https://github.com/features/actions">GitHub Action</a> will deploy your project to <a href="https://pages.github.com/">GitHub Pages</a>. It can be configured to upload your production-ready code into any branch you'd like, including <b>gh-pages</b> and <b>docs</b>.
</p>
<p align="center">
<img src="./assets/screenshot.png">
</p>
## Getting Started :airplane:
@ -24,7 +56,12 @@ jobs:
with:
persist-credentials: false
- name: Build and Deploy 🚀
- name: Install and Build 🔧 # This example project is built using npm and outputs the result to the 'build' folder. Replace with the commands required to build your project, or remove this step entirely if your site is pre-built.
run: |
npm install
npm run build
- name: Deploy 🚀
uses: JamesIves/github-pages-deploy-action@releases/v3
with:
ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
@ -78,7 +115,7 @@ For more information regarding the [action interface please click here](https://
## Configuration 📁
The `with` portion of the workflow **must** be configured before the action will work. You can add these in the `with` section found in the examples above. Any `secrets` must be referenced using the bracket syntax and stored in the GitHub repositories `Settings/Secrets` menu. You can learn more about setting environment variables with GitHub actions [here](https://help.github.com/en/articles/workflow-syntax-for-github-actions#jobsjob_idstepsenv).
The `with` portion of the workflow **must** be configured before the action will work. You can add these in the `with` section found in the examples above. Any `secrets` must be referenced using the bracket syntax and stored in the GitHub repositories `Settings/Secrets` menu. You can learn more about setting environment variables with GitHub actions [here](https://help.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets#creating-encrypted-secrets).
#### Required Setup
@ -101,16 +138,16 @@ In addition to the deployment options you must also configure the following.
| Key | Value Information | Type | Required |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | -------- |
| `GIT_CONFIG_NAME` | Allows you to customize the name that is attached to the GitHub config which is used when pushing the deployment commits. If this is not included it will use the name in the GitHub context, followed by the name of the action. | `with` | **No** |
| `GIT_CONFIG_EMAIL` | Allows you to customize the email that is attached to the GitHub config which is used when pushing the deployment commits. If this is not included it will use the email in the GitHub context, followed by a generic noreply GitHub email. | `with` | **No** |
| `GIT_CONFIG_NAME` | Allows you to customize the name that is attached to the git config which is used when pushing the deployment commits. If this is not included it will use the name in the GitHub context, followed by the name of the action. | `with` | **No** |
| `GIT_CONFIG_EMAIL` | Allows you to customize the email that is attached to the git config which is used when pushing the deployment commits. If this is not included it will use the email in the GitHub context, followed by a generic noreply GitHub email. | `with` | **No** |
| `REPOSITORY_NAME` | Allows you to speicfy a different repository path so long as you have permissions to push to it. This should be formatted like so: `JamesIves/github-pages-deploy-action`. | `with` | **No** |
| `TARGET_FOLDER` | 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. | `with` | **No** |
| `BASE_BRANCH` | The base branch of your repository which you'd like to checkout prior to deploying. This defaults to the current commit [SHA](http://en.wikipedia.org/wiki/SHA-1) that triggered the build followed by `master` if it doesn't exist. This is useful for making deployments from another branch, and also may be necessary when using a scheduled job. | `with` | **No** |
| `COMMIT_MESSAGE` | If you need to customize the commit message for an integration you can do so. | `with` | **No** |
| `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** |
| `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** |
| `DEBUG` | By default the git commands are hidden from the log. If you'd like to turn them on you can toggle this to `true`. **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**. | `with` | **No** |
With the action correctly configured you should see the workflow trigger the deployment under the configured conditions.
@ -126,15 +163,15 @@ ssh-keygen -t rsa -b 4096 -C "youremailhere@example.com" -N ""
Once you've generated the key pair you must add the contents of the public key within your repositories [deploy keys menu](https://developer.github.com/v3/guides/managing-deploy-keys/). You can find this option by going to `Settings > Deploy Keys`, you can name the public key whatever you want, but you **do** need to give it write access. Afterwards add the contents of the private key to the `Settings > Secrets` menu as `DEPLOY_KEY`.
With this configured you must add the `ssh-agent` step to your workflow and set `SSH` to `true` within the deploy action.
With this configured you must add the `ssh-agent` step to your workflow and set `SSH` to `true` within the deploy action. There are several SSH actions available on the [GitHub marketplace](https://github.com/marketplace?type=actions) for you to choose from.
```yml
- name: Install SSH Client
- name: Install SSH Client 🔑
uses: webfactory/ssh-agent@v0.2.0
with:
ssh-private-key: ${{ secrets.DEPLOY_KEY }}
- name: Build and Deploy 🚀
- name: Deploy 🚀
uses: JamesIves/github-pages-deploy-action@releases/v3
with:
SSH: true
@ -160,17 +197,17 @@ jobs:
with:
persist-credentials: false
- name: Install
- name: Install and Build 🔧 # This example project is built using npm and outputs the result to the 'build' folder. Replace with the commands required to build your project, or remove this step entirely if your site is pre-built.
run: |
npm install
npm run-script build
npm run build
- name: Install SSH Client 🔑
uses: webfactory/ssh-agent@v0.2.0 # This step installs the ssh client into the workflow run. There's many options available for this on the action marketplace.
with:
ssh-private-key: ${{ secrets.DEPLOY_KEY }}
- name: Build and Deploy Repo 🚀
- name: Deploy 🚀
uses: JamesIves/github-pages-deploy-action@releases/v3-test
with:
BASE_BRANCH: master
@ -212,12 +249,12 @@ jobs:
with:
persist-credentials: false
- name: Install # The project is built using npm and placed in the 'build' folder.
- name: Install and Build 🔧 # This example project is built using npm and outputs the result to the 'build' folder. Replace with the commands required to build your project, or remove this step entirely if your site is pre-built.
run: |
npm install
npm run-script build
npm run build
- name: Upload Artifacts # The project is then uploaded as an artifact named 'site'.
- name: Upload Artifacts 🔺 # The project is then uploaded as an artifact named 'site'.
uses: actions/upload-artifact@v1
with:
name: site
@ -232,12 +269,12 @@ jobs:
with:
persist-credentials: false
- name: Download Artifacts # The built project is downloaded into the 'site' folder.
- name: Download Artifacts 🔻 # The built project is downloaded into the 'site' folder.
uses: actions/download-artifact@v1
with:
name: site
- name: Build and Deploy 🚀
- name: Deploy 🚀
uses: JamesIves/github-pages-deploy-action@releases/v3
with:
ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
@ -255,11 +292,11 @@ jobs:
If you use a [container](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobsjob_idcontainer) in your workflow you may need to run an additional step to install `rsync` as this action depends on it. You can view an example of this below.
```yml
- name: Install rsync
- name: Install rsync 📚
run: |
apt-get update && apt-get install -y rsync
- name: Deploy
- name: Deploy 🚀
uses: JamesIves/github-pages-deploy-action@releases/v3
```
@ -267,4 +304,10 @@ If you use a [container](https://help.github.com/en/actions/automating-your-work
### Additional Build Files 📁
This action maintains the full Git history of the deployment branch. Therefore if you're using a custom domain and require a `CNAME` file, or if you require the use of a `.nojekyll` file, you can safely commit these files directly into deployment branch without them being overridden after each deployment.
If you're using a custom domain and require a `CNAME` file, or if you require the use of a `.nojekyll` file, you can safely commit these files directly into deployment branch without them being overridden after each deployment.
---
### 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).

View File

@ -1 +1 @@
process.env.UNIT_TEST = "true"
process.env.UNIT_TEST = 'true'

View File

@ -7,7 +7,7 @@ jest.mock('@actions/exec', () => ({
describe('execute', () => {
it('should be called with the correct arguments', async () => {
await stdout('hello')
stdout('hello')
await execute('echo Montezuma', './')
expect(exec).toBeCalledWith('echo Montezuma', [], {
@ -20,9 +20,9 @@ describe('execute', () => {
})
it('should not silence the input when INPUT_DEBUG is defined', async () => {
process.env['DEBUG_DEPLOY_ACTION'] = 'yes'
process.env['RUNNER_DEBUG'] = '1'
await stdout('hello')
stdout('hello')
await execute('echo Montezuma', './')
expect(exec).toBeCalledWith('echo Montezuma', [], {

View File

@ -5,13 +5,14 @@ process.env['GITHUB_SHA'] = '123'
import {action} from '../src/constants'
import {deploy, generateBranch, init, switchToBaseBranch} from '../src/git'
import {execute} from '../src/execute'
import {setFailed} from '@actions/core'
const originalAction = JSON.stringify(action)
jest.mock('@actions/core', () => ({
setFailed: jest.fn(),
getInput: jest.fn()
getInput: jest.fn(),
isDebug: jest.fn(),
info: jest.fn()
}))
jest.mock('../src/execute', () => ({
@ -318,6 +319,24 @@ describe('git', () => {
expect(execute).toBeCalledTimes(12)
})
it('should execute commands with single commit toggled', async () => {
Object.assign(action, {
folder: 'build',
branch: 'branch',
gitHubToken: '123',
singleCommit: true,
pusher: {
name: 'asd',
email: 'as@cat'
}
})
await deploy(action)
// Includes the call to generateBranch
expect(execute).toBeCalledTimes(18)
})
it('should execute commands with clean options, ommits sha commit message', async () => {
process.env.GITHUB_SHA = ''
Object.assign(action, {

View File

@ -18,7 +18,9 @@ jest.mock('../src/execute', () => ({
jest.mock('@actions/core', () => ({
setFailed: jest.fn(),
getInput: jest.fn(),
exportVariable: jest.fn()
exportVariable: jest.fn(),
isDebug: jest.fn(),
info: jest.fn()
}))
describe('main', () => {

View File

@ -159,7 +159,7 @@ describe('util', () => {
gitHubToken: 'anothersecret123333'
}
process.env['INPUT_DEBUG'] = 'true'
process.env['RUNNER_DEBUG'] = '1'
const string = `This is an error message! It contains ${action.accessToken} and ${action.gitHubToken} and ${action.repositoryPath}`
expect(suppressSensitiveInformation(string, action)).toBe(

View File

@ -64,6 +64,6 @@ inputs:
description: "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."
required: false
DEBUG:
description: "By default the git commands are hidden from the log. If you'd like to turn them on you can toggle this to true."
required: false
SINGLE_COMMIT:
description: "This option can be used if you'd prefer to have a single commit on the deployment branch instead of maintaining the full history."
required: false

BIN
assets/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

View File

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 45 KiB

View File

@ -8,7 +8,7 @@ module.exports = {
'^.+\\.ts$': 'ts-jest'
},
verbose: true,
setupFiles: ["<rootDir>/__tests__/env.js"],
setupFiles: ['<rootDir>/__tests__/env.js'],
collectCoverage: true,
collectCoverageFrom: ['src/*.ts','!src/constants.ts']
}
collectCoverageFrom: ['src/*.ts', '!src/constants.ts']
}

View File

@ -2,7 +2,7 @@
"name": "github-pages-deploy-action",
"description": "GitHub action for building a project and deploying it to GitHub pages.",
"author": "James Ives <iam@jamesiv.es>",
"version": "3.4.0",
"version": "3.4.2",
"license": "MIT",
"main": "lib/lib.js",
"types": "lib/lib.d.ts",
@ -33,20 +33,20 @@
"deployment"
],
"dependencies": {
"@actions/core": "^1.2.0",
"@actions/exec": "^1.0.2",
"@actions/github": "^2.0.0"
"@actions/core": "1.2.3",
"@actions/exec": "1.0.3",
"@actions/github": "2.1.1"
},
"devDependencies": {
"@types/jest": "^25.1.0",
"@types/node": "^13.1.2",
"jest": "^25.1.0",
"jest-circus": "^25.1.0",
"prettier": "^1.19.1",
"ts-jest": "^25.0.0",
"eslint": "^5.16.0",
"eslint-plugin-github": "^2.0.0",
"eslint-plugin-jest": "^22.21.0",
"typescript": "^3.7.4"
"@types/jest": "25.1.4",
"@types/node": "13.9.5",
"jest": "25.2.4",
"jest-circus": "25.2.4",
"prettier": "2.0.2",
"ts-jest": "25.3.0",
"eslint": "6.8.0",
"eslint-plugin-github": "3.4.1",
"eslint-plugin-jest": "23.8.2",
"typescript": "3.8.3"
}
}

View File

@ -13,13 +13,11 @@ export interface ActionInterface {
/** The branch that the action should deploy to. */
branch: string
/** 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. */
clean?: string | boolean
clean?: boolean | null
/** If you need to use CLEAN but you'd like to preserve certain files or folders you can use this option. */
cleanExclude?: string | string[]
/** If you need to customize the commit message for an integration you can do so. */
commitMessage?: string
/** Unhides the Git commands from the function terminal. */
debug?: boolean | string
/** The default branch of the deployment. Similar to baseBranch if you're using this action as a module. */
defaultBranch?: string
/** The git config email. */
@ -29,17 +27,19 @@ export interface ActionInterface {
/** GitHub deployment token. */
gitHubToken?: string | null
/** Determines if the action is running in test mode or not. */
isTest?: string | undefined | null
isTest?: boolean | null
/** The git config name. */
name?: string
/** The repository path, for example JamesIves/github-pages-deploy-action */
/** The repository path, for example JamesIves/github-pages-deploy-action. */
repositoryName?: string
/** The fully qualified repositpory path, this gets auto generated if repositoryName is provided. */
repositoryPath?: string
/** The root directory where your project lives. */
root?: string
/** Wipes the commit history from the deployment branch in favor of a single commit. */
singleCommit?: boolean | null
/** Set to true if you're using an ssh client in your build step. */
ssh?: string | boolean | null
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. */
targetFolder?: string
/** The token type, ie ssh/github token/access token, this gets automatically generated. */
@ -55,18 +55,21 @@ export const action: ActionInterface = {
folder: getInput('FOLDER'),
branch: getInput('BRANCH'),
commitMessage: getInput('COMMIT_MESSAGE'),
clean: getInput('CLEAN'),
clean: !isNullOrUndefined(getInput('CLEAN'))
? getInput('CLEAN').toLowerCase() === 'true'
: false,
cleanExclude: getInput('CLEAN_EXCLUDE'),
debug: getInput('DEBUG'),
defaultBranch: process.env.GITHUB_SHA ? process.env.GITHUB_SHA : 'master',
isTest: process.env.UNIT_TEST,
ssh: getInput('SSH'),
isTest: process.env.UNIT_TEST
? process.env.UNIT_TEST.toLowerCase() === 'true'
: false,
email: !isNullOrUndefined(getInput('GIT_CONFIG_EMAIL'))
? getInput('GIT_CONFIG_EMAIL')
: pusher && pusher.email
? pusher.email
: `${process.env.GITHUB_ACTOR ||
'github-pages-deploy-action'}@users.noreply.github.com`,
: `${
process.env.GITHUB_ACTOR || 'github-pages-deploy-action'
}@users.noreply.github.com`,
gitHubToken: getInput('GITHUB_TOKEN'),
name: !isNullOrUndefined(getInput('GIT_CONFIG_NAME'))
? getInput('GIT_CONFIG_NAME')
@ -81,6 +84,12 @@ export const action: ActionInterface = {
? repository.full_name
: process.env.GITHUB_REPOSITORY,
root: '.',
singleCommit: !isNullOrUndefined(getInput('SINGLE_COMMIT'))
? getInput('SINGLE_COMMIT').toLowerCase() === 'true'
: false,
ssh: !isNullOrUndefined(getInput('SSH'))
? getInput('SSH').toLowerCase() === 'true'
: false,
targetFolder: getInput('TARGET_FOLDER'),
workspace: process.env.GITHUB_WORKSPACE || ''
}

View File

@ -1,19 +1,20 @@
import {isDebug} from '@actions/core'
import {exec} from '@actions/exec'
let output: string
/** Wrapper around the GitHub toolkit exec command which returns the output.
* Also allows you to easily toggle the current working directory.
* @param cmd = The command to execute.
* @param cwd - The current working directory.
* @returns - The output from the command.
*
* @param {string} cmd - The command to execute.
* @param {string} cwd - The current working directory.
*/
export async function execute(cmd: string, cwd: string): Promise<any> {
output = ''
await exec(cmd, [], {
// Silences the input unless the INPUT_DEBUG flag is set.
silent: process.env.DEBUG_DEPLOY_ACTION ? false : true,
silent: isDebug() ? false : true,
cwd,
listeners: {
stdout

View File

@ -1,3 +1,4 @@
import {info} from '@actions/core'
import {ActionInterface} from './constants'
import {execute} from './execute'
import {
@ -11,8 +12,8 @@ export async function init(action: ActionInterface): Promise<void | Error> {
try {
hasRequiredParameters(action)
console.log(`Deploying using ${action.tokenType}... 🔑`)
console.log('Configuring git...')
info(`Deploying using ${action.tokenType} 🔑`)
info('Configuring git…')
await execute(`git init`, action.workspace)
await execute(`git config user.name "${action.name}"`, action.workspace)
@ -24,7 +25,7 @@ export async function init(action: ActionInterface): Promise<void | Error> {
)
await execute(`git fetch`, action.workspace)
console.log('Git configured... 🔧')
info('Git configured… 🔧')
} catch (error) {
throw new Error(
`There was an error initializing the repository: ${suppressSensitiveInformation(
@ -63,13 +64,13 @@ export async function generateBranch(action: ActionInterface): Promise<void> {
try {
hasRequiredParameters(action)
console.log(`Creating the ${action.branch} branch...`)
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 commit --allow-empty -m "Initial ${action.branch} commit."`,
`git commit --allow-empty -m "Initial ${action.branch} commit"`,
action.workspace
)
await execute(
@ -78,7 +79,7 @@ export async function generateBranch(action: ActionInterface): Promise<void> {
)
await execute(`git fetch`, action.workspace)
console.log(`Created the ${action.branch} branch... 🔧`)
info(`Created the ${action.branch} branch 🔧`)
} catch (error) {
throw new Error(
`There was an error creating the deployment branch: ${suppressSensitiveInformation(
@ -93,11 +94,18 @@ export async function generateBranch(action: ActionInterface): Promise<void> {
export async function deploy(action: ActionInterface): Promise<void> {
const temporaryDeploymentDirectory = 'gh-action-temp-deployment-folder'
const temporaryDeploymentBranch = 'gh-action-temp-deployment-branch'
console.log('Starting to commit changes...')
info('Starting to commit changes…')
try {
hasRequiredParameters(action)
const commitMessage = `${
!isNullOrUndefined(action.commitMessage)
? action.commitMessage
: `Deploying to ${action.branch} from ${action.baseBranch}`
} ${process.env.GITHUB_SHA ? `@ ${process.env.GITHUB_SHA}` : ''} 🚀`
/*
Checks to see if the remote exists prior to deploying.
If the branch doesn't exist it gets created here as an orphan.
@ -132,7 +140,7 @@ export async function deploy(action: ActionInterface): Promise<void> {
excludes += `--exclude ${item} `
}
} catch {
console.log(
info(
'There was an error parsing your CLEAN_EXCLUDE items. Please refer to the README for more details. ❌'
)
}
@ -165,7 +173,7 @@ export async function deploy(action: ActionInterface): Promise<void> {
)
if (!hasFilesToCommit && !action.isTest) {
console.log('There is nothing to commit. Exiting early... 📭')
info('There is nothing to commit. Exiting early… 📭')
return
}
@ -179,13 +187,7 @@ export async function deploy(action: ActionInterface): Promise<void> {
`${action.workspace}/${temporaryDeploymentDirectory}`
)
await execute(
`git commit -m "${
!isNullOrUndefined(action.commitMessage)
? action.commitMessage
: `Deploying to ${action.branch} from ${action.baseBranch}`
} ${
process.env.GITHUB_SHA ? `- ${process.env.GITHUB_SHA}` : ''
} 🚀" --quiet`,
`git commit -m "${commitMessage}" --quiet`,
`${action.workspace}/${temporaryDeploymentDirectory}`
)
await execute(
@ -193,10 +195,37 @@ export async function deploy(action: ActionInterface): Promise<void> {
`${action.workspace}/${temporaryDeploymentDirectory}`
)
console.log(`Changes committed to the ${action.branch} branch... 📦`)
info(`Changes committed to the ${action.branch} branch 📦`)
// Cleans up temporary files/folders and restores the git state.
console.log('Running post deployment cleanup jobs...')
info('Running post deployment cleanup jobs…')
if (action.singleCommit) {
await execute(`git fetch ${action.repositoryPath}`, action.workspace)
await execute(
`git checkout --orphan ${action.branch}-temp`,
`${action.workspace}/${temporaryDeploymentDirectory}`
)
await execute(
`git add --all .`,
`${action.workspace}/${temporaryDeploymentDirectory}`
)
await execute(
`git commit -m "${commitMessage}" --quiet`,
`${action.workspace}/${temporaryDeploymentDirectory}`
)
await execute(
`git branch -M ${action.branch}-temp ${action.branch}`,
`${action.workspace}/${temporaryDeploymentDirectory}`
)
await execute(
`git push origin ${action.branch} --force`,
`${action.workspace}/${temporaryDeploymentDirectory}`
)
info('Cleared git history… 🚿')
}
await execute(
`git checkout --progress --force ${action.defaultBranch}`,
action.workspace

View File

@ -1,16 +1,19 @@
import {exportVariable, setFailed} from '@actions/core'
import {info, setFailed} from '@actions/core'
import {action, ActionInterface} from './constants'
import {deploy, generateBranch, init} from './git'
import {generateRepositoryPath, generateTokenType} from './util'
/** Initializes and runs the action. */
/** Initializes and runs the action.
*
* @param {object} configuration - The action configuration.
*/
export default async function run(
configuration: ActionInterface
): Promise<void> {
let errorState = false
try {
console.log('Checking configuration and starting deployment...🚦')
info('Checking configuration and starting deployment… 🚦')
const settings = {
...action,
@ -21,18 +24,13 @@ export default async function run(
settings.repositoryPath = generateRepositoryPath(settings)
settings.tokenType = generateTokenType(settings)
if (settings.debug) {
// Sets the debug flag if passed as an arguement.
exportVariable('DEBUG_DEPLOY_ACTION', 'debug')
}
await init(settings)
await deploy(settings)
} catch (error) {
errorState = true
setFailed(error.message)
} finally {
console.log(
info(
`${
errorState
? 'Deployment Failed ❌'

View File

@ -1,4 +1,4 @@
import {getInput} from '@actions/core'
import {isDebug} from '@actions/core'
import {ActionInterface} from './constants'
/* Utility function that checks to see if a value is undefined or not. */
@ -19,10 +19,9 @@ export const generateTokenType = (action: ActionInterface): string =>
export const generateRepositoryPath = (action: ActionInterface): string =>
action.ssh
? `git@github.com:${action.repositoryName}`
: `https://${action.accessToken ||
`x-access-token:${action.gitHubToken}`}@github.com/${
action.repositoryName
}.git`
: `https://${
action.accessToken || `x-access-token:${action.gitHubToken}`
}@github.com/${action.repositoryName}.git`
/* Checks for the required tokens and formatting. Throws an error if any case is matched. */
export const hasRequiredParameters = (action: ActionInterface): void => {
@ -59,7 +58,7 @@ export const suppressSensitiveInformation = (
): string => {
let value = str
if (getInput('DEBUG')) {
if (isDebug()) {
// Data is unmasked in debug mode.
return value
}

1244
yarn.lock

File diff suppressed because it is too large Load Diff