mirror of
https://github.com/JamesIves/github-pages-deploy-action.git
synced 2023-12-15 20:03:39 +08:00
Feat: add support for checking if source folder exists (#463)
* Refactor: check parameters in `init` * Test: add test for checking if folder exist - rm unnecessary tests * Test: fix wrong error message * Refactor: mv initialization functions to `run` Refactor: rm `action.root`, `action.rootPath` Refactor: `generateFolderPath`, `hasRequiredParameters` Test: rm some tests for `init`, add tests for `checkParameters`
This commit is contained in:
parent
dc96a8ff00
commit
dc667b3217
@ -32,171 +32,6 @@ describe('git', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('init', () => {
|
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',
|
|
||||||
gitHubToken: '123',
|
|
||||||
pusher: {
|
|
||||||
name: 'asd',
|
|
||||||
email: 'as@cat'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
await init(action)
|
|
||||||
expect(execute).toBeCalledTimes(6)
|
|
||||||
})
|
|
||||||
|
|
||||||
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',
|
|
||||||
accessToken: '123',
|
|
||||||
pusher: {
|
|
||||||
name: 'asd',
|
|
||||||
email: 'as@cat'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
await init(action)
|
|
||||||
expect(execute).toBeCalledTimes(6)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should execute commands if SSH is true', async () => {
|
|
||||||
Object.assign(action, {
|
|
||||||
silent: false,
|
|
||||||
repositoryPath: 'JamesIves/github-pages-deploy-action',
|
|
||||||
folder: 'assets',
|
|
||||||
branch: 'branch',
|
|
||||||
ssh: true,
|
|
||||||
pusher: {
|
|
||||||
name: 'asd',
|
|
||||||
email: 'as@cat'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
await init(action)
|
|
||||||
|
|
||||||
expect(execute).toBeCalledTimes(6)
|
|
||||||
})
|
|
||||||
|
|
||||||
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',
|
|
||||||
pusher: {
|
|
||||||
name: 'asd',
|
|
||||||
email: 'as@cat'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
try {
|
|
||||||
await init(action)
|
|
||||||
} catch (e) {
|
|
||||||
expect(execute).toBeCalledTimes(0)
|
|
||||||
expect(e.message).toMatch(
|
|
||||||
'There was an error initializing the repository: No deployment token/method was provided. You must provide the action with either a Personal Access Token or the GitHub Token secret in order to deploy. If you wish to use an ssh deploy token then you must set SSH to true. ❌'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
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',
|
|
||||||
pusher: {
|
|
||||||
name: 'asd',
|
|
||||||
email: 'as@cat'
|
|
||||||
},
|
|
||||||
accessToken: ''
|
|
||||||
})
|
|
||||||
|
|
||||||
try {
|
|
||||||
await init(action)
|
|
||||||
} catch (e) {
|
|
||||||
expect(execute).toBeCalledTimes(0)
|
|
||||||
expect(e.message).toMatch(
|
|
||||||
'There was an error initializing the repository: No deployment token/method was provided. You must provide the action with either a Personal Access Token or the GitHub Token secret in order to deploy. If you wish to use an ssh deploy token then you must set SSH to true. ❌'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should fail if there is no folder', async () => {
|
|
||||||
Object.assign(action, {
|
|
||||||
silent: false,
|
|
||||||
repositoryPath: 'JamesIves/github-pages-deploy-action',
|
|
||||||
gitHubToken: '123',
|
|
||||||
branch: 'branch',
|
|
||||||
pusher: {
|
|
||||||
name: 'asd',
|
|
||||||
email: 'as@cat'
|
|
||||||
},
|
|
||||||
folder: null,
|
|
||||||
ssh: true
|
|
||||||
})
|
|
||||||
|
|
||||||
try {
|
|
||||||
await init(action)
|
|
||||||
} catch (e) {
|
|
||||||
expect(execute).toBeCalledTimes(0)
|
|
||||||
expect(e.message).toMatch(
|
|
||||||
'There was an error initializing the repository: You must provide the action with a folder to deploy. ❌'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should fail if there is no provided repository path', async () => {
|
|
||||||
Object.assign(action, {
|
|
||||||
silent: true,
|
|
||||||
repositoryPath: null,
|
|
||||||
folder: 'assets',
|
|
||||||
branch: 'branch',
|
|
||||||
pusher: {
|
|
||||||
name: 'asd',
|
|
||||||
email: 'as@cat'
|
|
||||||
},
|
|
||||||
gitHubToken: '123',
|
|
||||||
accessToken: null,
|
|
||||||
ssh: null
|
|
||||||
})
|
|
||||||
|
|
||||||
try {
|
|
||||||
await init(action)
|
|
||||||
} catch (e) {
|
|
||||||
expect(execute).toBeCalledTimes(0)
|
|
||||||
expect(e.message).toMatch(
|
|
||||||
'There was an error initializing the repository: No deployment token/method was provided. You must provide the action with either a Personal Access Token or the GitHub Token secret in order to deploy. If you wish to use an ssh deploy token then you must set SSH to true. '
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should not fail if root is used', async () => {
|
|
||||||
Object.assign(action, {
|
|
||||||
silent: false,
|
|
||||||
repositoryPath: 'JamesIves/github-pages-deploy-action',
|
|
||||||
accessToken: '123',
|
|
||||||
branch: 'branch',
|
|
||||||
folder: '.',
|
|
||||||
root: '.',
|
|
||||||
pusher: {
|
|
||||||
name: 'asd',
|
|
||||||
email: 'as@cat'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
await init(action)
|
|
||||||
|
|
||||||
expect(execute).toBeCalledTimes(6)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should stash changes if preserve is true', async () => {
|
it('should stash changes if preserve is true', async () => {
|
||||||
Object.assign(action, {
|
Object.assign(action, {
|
||||||
silent: false,
|
silent: false,
|
||||||
@ -213,7 +48,6 @@ describe('git', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
await init(action)
|
await init(action)
|
||||||
|
|
||||||
expect(execute).toBeCalledTimes(7)
|
expect(execute).toBeCalledTimes(7)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -234,27 +68,6 @@ describe('git', () => {
|
|||||||
await generateBranch(action)
|
await generateBranch(action)
|
||||||
expect(execute).toBeCalledTimes(6)
|
expect(execute).toBeCalledTimes(6)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should fail if there is no branch', async () => {
|
|
||||||
Object.assign(action, {
|
|
||||||
silent: false,
|
|
||||||
accessToken: '123',
|
|
||||||
branch: null,
|
|
||||||
folder: '.',
|
|
||||||
pusher: {
|
|
||||||
name: 'asd',
|
|
||||||
email: 'as@cat'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
try {
|
|
||||||
await generateBranch(action)
|
|
||||||
} catch (e) {
|
|
||||||
expect(e.message).toMatch(
|
|
||||||
'There was an error creating the deployment branch: Branch is required. ❌'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('switchToBaseBranch', () => {
|
describe('switchToBaseBranch', () => {
|
||||||
@ -290,31 +103,6 @@ describe('git', () => {
|
|||||||
await switchToBaseBranch(action)
|
await switchToBaseBranch(action)
|
||||||
expect(execute).toBeCalledTimes(1)
|
expect(execute).toBeCalledTimes(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should fail if one of the required parameters is not available', async () => {
|
|
||||||
Object.assign(action, {
|
|
||||||
silent: false,
|
|
||||||
baseBranch: '123',
|
|
||||||
accessToken: null,
|
|
||||||
gitHubToken: null,
|
|
||||||
ssh: null,
|
|
||||||
branch: 'branch',
|
|
||||||
folder: null,
|
|
||||||
pusher: {
|
|
||||||
name: 'asd',
|
|
||||||
email: 'as@cat'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
try {
|
|
||||||
await switchToBaseBranch(action)
|
|
||||||
} catch (e) {
|
|
||||||
expect(execute).toBeCalledTimes(0)
|
|
||||||
expect(e.message).toMatch(
|
|
||||||
'There was an error switching to the base branch: No deployment token/method was provided. You must provide the action with either a Personal Access Token or the GitHub Token secret in order to deploy. If you wish to use an ssh deploy token then you must set SSH to true. ❌'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('deploy', () => {
|
describe('deploy', () => {
|
||||||
@ -488,31 +276,5 @@ describe('git', () => {
|
|||||||
expect(rmRF).toBeCalledTimes(1)
|
expect(rmRF).toBeCalledTimes(1)
|
||||||
expect(response).toBe(Status.SKIPPED)
|
expect(response).toBe(Status.SKIPPED)
|
||||||
})
|
})
|
||||||
|
|
||||||
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,
|
|
||||||
accessToken: null,
|
|
||||||
gitHubToken: null,
|
|
||||||
pusher: {
|
|
||||||
name: 'asd',
|
|
||||||
email: 'as@cat'
|
|
||||||
},
|
|
||||||
isTest: false // Setting this env variable to false means there will never be anything to commit and the action will exit early.
|
|
||||||
})
|
|
||||||
|
|
||||||
try {
|
|
||||||
await deploy(action)
|
|
||||||
} catch (e) {
|
|
||||||
expect(execute).toBeCalledTimes(1)
|
|
||||||
expect(rmRF).toBeCalledTimes(1)
|
|
||||||
expect(e.message).toMatch(
|
|
||||||
'The deploy step encountered an error: No deployment token/method was provided. You must provide the action with either a Personal Access Token or the GitHub Token secret in order to deploy. If you wish to use an ssh deploy token then you must set SSH to true. ❌'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
|
import {ActionInterface} from '../src/constants'
|
||||||
import {
|
import {
|
||||||
isNullOrUndefined,
|
isNullOrUndefined,
|
||||||
generateTokenType,
|
generateTokenType,
|
||||||
generateRepositoryPath,
|
generateRepositoryPath,
|
||||||
generateFolderPath,
|
generateFolderPath,
|
||||||
suppressSensitiveInformation
|
suppressSensitiveInformation,
|
||||||
|
checkParameters
|
||||||
} from '../src/util'
|
} from '../src/util'
|
||||||
|
|
||||||
describe('util', () => {
|
describe('util', () => {
|
||||||
@ -22,13 +24,17 @@ describe('util', () => {
|
|||||||
const value = 'montezuma'
|
const value = 'montezuma'
|
||||||
expect(isNullOrUndefined(value)).toBeFalsy()
|
expect(isNullOrUndefined(value)).toBeFalsy()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should return false if the value is empty string', async () => {
|
||||||
|
const value = ''
|
||||||
|
expect(isNullOrUndefined(value)).toBeTruthy()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('generateTokenType', () => {
|
describe('generateTokenType', () => {
|
||||||
it('should return ssh if ssh is provided', async () => {
|
it('should return ssh if ssh is provided', async () => {
|
||||||
const action = {
|
const action = {
|
||||||
branch: '123',
|
branch: '123',
|
||||||
root: '.',
|
|
||||||
workspace: 'src/',
|
workspace: 'src/',
|
||||||
folder: 'build',
|
folder: 'build',
|
||||||
gitHubToken: null,
|
gitHubToken: null,
|
||||||
@ -42,7 +48,6 @@ describe('util', () => {
|
|||||||
it('should return access token if access token is provided', async () => {
|
it('should return access token if access token is provided', async () => {
|
||||||
const action = {
|
const action = {
|
||||||
branch: '123',
|
branch: '123',
|
||||||
root: '.',
|
|
||||||
workspace: 'src/',
|
workspace: 'src/',
|
||||||
folder: 'build',
|
folder: 'build',
|
||||||
gitHubToken: null,
|
gitHubToken: null,
|
||||||
@ -56,7 +61,6 @@ describe('util', () => {
|
|||||||
it('should return github token if github token is provided', async () => {
|
it('should return github token if github token is provided', async () => {
|
||||||
const action = {
|
const action = {
|
||||||
branch: '123',
|
branch: '123',
|
||||||
root: '.',
|
|
||||||
workspace: 'src/',
|
workspace: 'src/',
|
||||||
folder: 'build',
|
folder: 'build',
|
||||||
gitHubToken: '123',
|
gitHubToken: '123',
|
||||||
@ -70,7 +74,6 @@ describe('util', () => {
|
|||||||
it('should return ... if no token is provided', async () => {
|
it('should return ... if no token is provided', async () => {
|
||||||
const action = {
|
const action = {
|
||||||
branch: '123',
|
branch: '123',
|
||||||
root: '.',
|
|
||||||
workspace: 'src/',
|
workspace: 'src/',
|
||||||
folder: 'build',
|
folder: 'build',
|
||||||
gitHubToken: null,
|
gitHubToken: null,
|
||||||
@ -87,7 +90,6 @@ describe('util', () => {
|
|||||||
const action = {
|
const action = {
|
||||||
repositoryName: 'JamesIves/github-pages-deploy-action',
|
repositoryName: 'JamesIves/github-pages-deploy-action',
|
||||||
branch: '123',
|
branch: '123',
|
||||||
root: '.',
|
|
||||||
workspace: 'src/',
|
workspace: 'src/',
|
||||||
folder: 'build',
|
folder: 'build',
|
||||||
gitHubToken: null,
|
gitHubToken: null,
|
||||||
@ -104,7 +106,6 @@ describe('util', () => {
|
|||||||
const action = {
|
const action = {
|
||||||
repositoryName: 'JamesIves/github-pages-deploy-action',
|
repositoryName: 'JamesIves/github-pages-deploy-action',
|
||||||
branch: '123',
|
branch: '123',
|
||||||
root: '.',
|
|
||||||
workspace: 'src/',
|
workspace: 'src/',
|
||||||
folder: 'build',
|
folder: 'build',
|
||||||
gitHubToken: null,
|
gitHubToken: null,
|
||||||
@ -121,7 +122,6 @@ describe('util', () => {
|
|||||||
const action = {
|
const action = {
|
||||||
repositoryName: 'JamesIves/github-pages-deploy-action',
|
repositoryName: 'JamesIves/github-pages-deploy-action',
|
||||||
branch: '123',
|
branch: '123',
|
||||||
root: '.',
|
|
||||||
workspace: 'src/',
|
workspace: 'src/',
|
||||||
folder: 'build',
|
folder: 'build',
|
||||||
gitHubToken: '123',
|
gitHubToken: '123',
|
||||||
@ -141,7 +141,6 @@ describe('util', () => {
|
|||||||
repositoryPath:
|
repositoryPath:
|
||||||
'https://x-access-token:supersecret999%%%@github.com/anothersecret123333',
|
'https://x-access-token:supersecret999%%%@github.com/anothersecret123333',
|
||||||
branch: '123',
|
branch: '123',
|
||||||
root: '.',
|
|
||||||
workspace: 'src/',
|
workspace: 'src/',
|
||||||
folder: 'build',
|
folder: 'build',
|
||||||
accessToken: 'supersecret999%%%',
|
accessToken: 'supersecret999%%%',
|
||||||
@ -161,7 +160,6 @@ describe('util', () => {
|
|||||||
repositoryPath:
|
repositoryPath:
|
||||||
'https://x-access-token:supersecret999%%%@github.com/anothersecret123333',
|
'https://x-access-token:supersecret999%%%@github.com/anothersecret123333',
|
||||||
branch: '123',
|
branch: '123',
|
||||||
root: '.',
|
|
||||||
workspace: 'src/',
|
workspace: 'src/',
|
||||||
folder: 'build',
|
folder: 'build',
|
||||||
accessToken: 'supersecret999%%%',
|
accessToken: 'supersecret999%%%',
|
||||||
@ -183,7 +181,6 @@ describe('util', () => {
|
|||||||
it('should return absolute path if folder name is provided', () => {
|
it('should return absolute path if folder name is provided', () => {
|
||||||
const action = {
|
const action = {
|
||||||
branch: '123',
|
branch: '123',
|
||||||
root: '.',
|
|
||||||
workspace: 'src/',
|
workspace: 'src/',
|
||||||
folder: 'build',
|
folder: 'build',
|
||||||
gitHubToken: null,
|
gitHubToken: null,
|
||||||
@ -191,13 +188,12 @@ describe('util', () => {
|
|||||||
ssh: null,
|
ssh: null,
|
||||||
silent: false
|
silent: false
|
||||||
}
|
}
|
||||||
expect(generateFolderPath(action, 'folder')).toEqual('src/build')
|
expect(generateFolderPath(action)).toEqual('src/build')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should return original path if folder name begins with /', () => {
|
it('should return original path if folder name begins with /', () => {
|
||||||
const action = {
|
const action = {
|
||||||
branch: '123',
|
branch: '123',
|
||||||
root: '.',
|
|
||||||
workspace: 'src/',
|
workspace: 'src/',
|
||||||
folder: '/home/user/repo/build',
|
folder: '/home/user/repo/build',
|
||||||
gitHubToken: null,
|
gitHubToken: null,
|
||||||
@ -205,15 +201,12 @@ describe('util', () => {
|
|||||||
ssh: null,
|
ssh: null,
|
||||||
silent: false
|
silent: false
|
||||||
}
|
}
|
||||||
expect(generateFolderPath(action, 'folder')).toEqual(
|
expect(generateFolderPath(action)).toEqual('/home/user/repo/build')
|
||||||
'/home/user/repo/build'
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should process as relative path if folder name begins with ./', () => {
|
it('should process as relative path if folder name begins with ./', () => {
|
||||||
const action = {
|
const action = {
|
||||||
branch: '123',
|
branch: '123',
|
||||||
root: '.',
|
|
||||||
workspace: 'src/',
|
workspace: 'src/',
|
||||||
folder: './build',
|
folder: './build',
|
||||||
gitHubToken: null,
|
gitHubToken: null,
|
||||||
@ -221,13 +214,12 @@ describe('util', () => {
|
|||||||
ssh: null,
|
ssh: null,
|
||||||
silent: false
|
silent: false
|
||||||
}
|
}
|
||||||
expect(generateFolderPath(action, 'folder')).toEqual('src/build')
|
expect(generateFolderPath(action)).toEqual('src/build')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should return absolute path if folder name begins with ~', () => {
|
it('should return absolute path if folder name begins with ~', () => {
|
||||||
const action = {
|
const action = {
|
||||||
branch: '123',
|
branch: '123',
|
||||||
root: '.',
|
|
||||||
workspace: 'src/',
|
workspace: 'src/',
|
||||||
folder: '~/repo/build',
|
folder: '~/repo/build',
|
||||||
gitHubToken: null,
|
gitHubToken: null,
|
||||||
@ -236,9 +228,102 @@ describe('util', () => {
|
|||||||
silent: false
|
silent: false
|
||||||
}
|
}
|
||||||
process.env.HOME = '/home/user'
|
process.env.HOME = '/home/user'
|
||||||
expect(generateFolderPath(action, 'folder')).toEqual(
|
expect(generateFolderPath(action)).toEqual('/home/user/repo/build')
|
||||||
'/home/user/repo/build'
|
})
|
||||||
)
|
})
|
||||||
|
|
||||||
|
describe('hasRequiredParameters', () => {
|
||||||
|
it('should fail if there is no provided GitHub Token, Access Token or SSH bool', () => {
|
||||||
|
const action = {
|
||||||
|
silent: false,
|
||||||
|
repositoryPath: undefined,
|
||||||
|
branch: 'branch',
|
||||||
|
folder: 'build',
|
||||||
|
workspace: 'src/'
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
checkParameters(action)
|
||||||
|
} catch (e) {
|
||||||
|
expect(e.message).toMatch(
|
||||||
|
'No deployment token/method was provided. You must provide the action with either a Personal Access Token or the GitHub Token secret in order to deploy. If you wish to use an ssh deploy token then you must set SSH to true.'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should fail if access token is defined but it is an empty string', () => {
|
||||||
|
const action = {
|
||||||
|
silent: false,
|
||||||
|
repositoryPath: undefined,
|
||||||
|
accessToken: '',
|
||||||
|
branch: 'branch',
|
||||||
|
folder: 'build',
|
||||||
|
workspace: 'src/'
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
checkParameters(action)
|
||||||
|
} catch (e) {
|
||||||
|
expect(e.message).toMatch(
|
||||||
|
'No deployment token/method was provided. You must provide the action with either a Personal Access Token or the GitHub Token secret in order to deploy. If you wish to use an ssh deploy token then you must set SSH to true.'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should fail if there is no branch', () => {
|
||||||
|
const action = {
|
||||||
|
silent: false,
|
||||||
|
repositoryPath: undefined,
|
||||||
|
accessToken: '123',
|
||||||
|
branch: '',
|
||||||
|
folder: 'build',
|
||||||
|
workspace: 'src/'
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
checkParameters(action)
|
||||||
|
} catch (e) {
|
||||||
|
expect(e.message).toMatch('Branch is required.')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should fail if there is no folder', () => {
|
||||||
|
const action = {
|
||||||
|
silent: false,
|
||||||
|
repositoryPath: undefined,
|
||||||
|
gitHubToken: '123',
|
||||||
|
branch: 'branch',
|
||||||
|
folder: '',
|
||||||
|
workspace: 'src/'
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
checkParameters(action)
|
||||||
|
} catch (e) {
|
||||||
|
expect(e.message).toMatch(
|
||||||
|
'You must provide the action with a folder to deploy.'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should fail if the folder does not exist in the tree', () => {
|
||||||
|
const action: ActionInterface = {
|
||||||
|
silent: false,
|
||||||
|
repositoryPath: undefined,
|
||||||
|
gitHubToken: '123',
|
||||||
|
branch: 'branch',
|
||||||
|
folder: 'notARealFolder',
|
||||||
|
workspace: '.'
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
action.folderPath = generateFolderPath(action)
|
||||||
|
checkParameters(action)
|
||||||
|
} catch (e) {
|
||||||
|
expect(e.message).toMatch(
|
||||||
|
`The ${action.folderPath} directory you're trying to deploy doesn't exist.`
|
||||||
|
)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -24,6 +24,7 @@ export interface ActionInterface {
|
|||||||
email?: string
|
email?: string
|
||||||
/** The folder to deploy. */
|
/** The folder to deploy. */
|
||||||
folder: string
|
folder: string
|
||||||
|
folderPath?: string
|
||||||
/** GitHub deployment token. */
|
/** GitHub deployment token. */
|
||||||
gitHubToken?: string | null
|
gitHubToken?: string | null
|
||||||
/** Determines if the action is running in test mode or not. */
|
/** Determines if the action is running in test mode or not. */
|
||||||
@ -38,8 +39,6 @@ export interface ActionInterface {
|
|||||||
repositoryName?: string
|
repositoryName?: string
|
||||||
/** The fully qualified repositpory path, this gets auto generated if repositoryName is provided. */
|
/** The fully qualified repositpory path, this gets auto generated if repositoryName is provided. */
|
||||||
repositoryPath?: string
|
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. */
|
/** Wipes the commit history from the deployment branch in favor of a single commit. */
|
||||||
singleCommit?: boolean | null
|
singleCommit?: boolean | null
|
||||||
/** Determines if the action should run in silent mode or not. */
|
/** Determines if the action should run in silent mode or not. */
|
||||||
@ -95,7 +94,6 @@ export const action: ActionInterface = {
|
|||||||
: repository && repository.full_name
|
: repository && repository.full_name
|
||||||
? repository.full_name
|
? repository.full_name
|
||||||
: process.env.GITHUB_REPOSITORY,
|
: process.env.GITHUB_REPOSITORY,
|
||||||
root: '.',
|
|
||||||
singleCommit: !isNullOrUndefined(getInput('SINGLE_COMMIT'))
|
singleCommit: !isNullOrUndefined(getInput('SINGLE_COMMIT'))
|
||||||
? getInput('SINGLE_COMMIT').toLowerCase() === 'true'
|
? getInput('SINGLE_COMMIT').toLowerCase() === 'true'
|
||||||
: false,
|
: false,
|
||||||
@ -109,8 +107,9 @@ export const action: ActionInterface = {
|
|||||||
workspace: process.env.GITHUB_WORKSPACE || ''
|
workspace: process.env.GITHUB_WORKSPACE || ''
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ActionFolders = NonNullable<
|
export type RequiredActionParameters = Pick<
|
||||||
Pick<ActionInterface, 'folder' | 'root'>
|
ActionInterface,
|
||||||
|
'accessToken' | 'gitHubToken' | 'ssh' | 'branch' | 'folder'
|
||||||
>
|
>
|
||||||
|
|
||||||
/** Status codes for the action. */
|
/** Status codes for the action. */
|
||||||
|
27
src/git.ts
27
src/git.ts
@ -3,18 +3,11 @@ import {mkdirP, rmRF} from '@actions/io'
|
|||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import {ActionInterface, Status} from './constants'
|
import {ActionInterface, Status} from './constants'
|
||||||
import {execute} from './execute'
|
import {execute} from './execute'
|
||||||
import {
|
import {isNullOrUndefined, suppressSensitiveInformation} from './util'
|
||||||
generateFolderPath,
|
|
||||||
hasRequiredParameters,
|
|
||||||
isNullOrUndefined,
|
|
||||||
suppressSensitiveInformation
|
|
||||||
} from './util'
|
|
||||||
|
|
||||||
/* Initializes git in the workspace. */
|
/* Initializes git in the workspace. */
|
||||||
export async function init(action: ActionInterface): Promise<void | Error> {
|
export async function init(action: ActionInterface): Promise<void | Error> {
|
||||||
try {
|
try {
|
||||||
hasRequiredParameters(action)
|
|
||||||
|
|
||||||
info(`Deploying using ${action.tokenType}… 🔑`)
|
info(`Deploying using ${action.tokenType}… 🔑`)
|
||||||
info('Configuring git…')
|
info('Configuring git…')
|
||||||
|
|
||||||
@ -73,8 +66,6 @@ export async function switchToBaseBranch(
|
|||||||
action: ActionInterface
|
action: ActionInterface
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
hasRequiredParameters(action)
|
|
||||||
|
|
||||||
await execute(
|
await execute(
|
||||||
`git checkout --progress --force ${
|
`git checkout --progress --force ${
|
||||||
action.baseBranch ? action.baseBranch : action.defaultBranch
|
action.baseBranch ? action.baseBranch : action.defaultBranch
|
||||||
@ -95,8 +86,6 @@ export async function switchToBaseBranch(
|
|||||||
/* Generates the branch if it doesn't exist on the remote. */
|
/* Generates the branch if it doesn't exist on the remote. */
|
||||||
export async function generateBranch(action: ActionInterface): Promise<void> {
|
export async function generateBranch(action: ActionInterface): Promise<void> {
|
||||||
try {
|
try {
|
||||||
hasRequiredParameters(action)
|
|
||||||
|
|
||||||
info(`Creating the ${action.branch} branch…`)
|
info(`Creating the ${action.branch} branch…`)
|
||||||
|
|
||||||
await switchToBaseBranch(action)
|
await switchToBaseBranch(action)
|
||||||
@ -131,8 +120,6 @@ export async function generateBranch(action: ActionInterface): Promise<void> {
|
|||||||
|
|
||||||
/* Runs the necessary steps to make the deployment. */
|
/* Runs the necessary steps to make the deployment. */
|
||||||
export async function deploy(action: ActionInterface): Promise<Status> {
|
export async function deploy(action: ActionInterface): Promise<Status> {
|
||||||
const folderPath = generateFolderPath(action, 'folder')
|
|
||||||
const rootPath = generateFolderPath(action, 'root')
|
|
||||||
const temporaryDeploymentDirectory =
|
const temporaryDeploymentDirectory =
|
||||||
'github-pages-deploy-action-temp-deployment-folder'
|
'github-pages-deploy-action-temp-deployment-folder'
|
||||||
const temporaryDeploymentBranch = `github-pages-deploy-action/${Math.random()
|
const temporaryDeploymentBranch = `github-pages-deploy-action/${Math.random()
|
||||||
@ -142,8 +129,6 @@ export async function deploy(action: ActionInterface): Promise<Status> {
|
|||||||
info('Starting to commit changes…')
|
info('Starting to commit changes…')
|
||||||
|
|
||||||
try {
|
try {
|
||||||
hasRequiredParameters(action)
|
|
||||||
|
|
||||||
const commitMessage = !isNullOrUndefined(action.commitMessage)
|
const commitMessage = !isNullOrUndefined(action.commitMessage)
|
||||||
? (action.commitMessage as string)
|
? (action.commitMessage as string)
|
||||||
: `Deploying to ${action.branch} from ${action.baseBranch} ${
|
: `Deploying to ${action.branch} from ${action.baseBranch} ${
|
||||||
@ -232,22 +217,24 @@ export async function deploy(action: ActionInterface): Promise<Status> {
|
|||||||
Allows the user to specify the root if '.' is provided.
|
Allows the user to specify the root if '.' is provided.
|
||||||
rsync is used to prevent file duplication. */
|
rsync is used to prevent file duplication. */
|
||||||
await execute(
|
await execute(
|
||||||
`rsync -q -av --checksum --progress ${folderPath}/. ${
|
`rsync -q -av --checksum --progress ${action.folderPath}/. ${
|
||||||
action.targetFolder
|
action.targetFolder
|
||||||
? `${temporaryDeploymentDirectory}/${action.targetFolder}`
|
? `${temporaryDeploymentDirectory}/${action.targetFolder}`
|
||||||
: temporaryDeploymentDirectory
|
: temporaryDeploymentDirectory
|
||||||
} ${
|
} ${
|
||||||
action.clean
|
action.clean
|
||||||
? `--delete ${excludes} ${
|
? `--delete ${excludes} ${
|
||||||
!fs.existsSync(`${folderPath}/CNAME`) ? '--exclude CNAME' : ''
|
!fs.existsSync(`${action.folderPath}/CNAME`)
|
||||||
|
? '--exclude CNAME'
|
||||||
|
: ''
|
||||||
} ${
|
} ${
|
||||||
!fs.existsSync(`${folderPath}/.nojekyll`)
|
!fs.existsSync(`${action.folderPath}/.nojekyll`)
|
||||||
? '--exclude .nojekyll'
|
? '--exclude .nojekyll'
|
||||||
: ''
|
: ''
|
||||||
}`
|
}`
|
||||||
: ''
|
: ''
|
||||||
} --exclude .ssh --exclude .git --exclude .github ${
|
} --exclude .ssh --exclude .git --exclude .github ${
|
||||||
folderPath === rootPath
|
action.folderPath === action.workspace
|
||||||
? `--exclude ${temporaryDeploymentDirectory}`
|
? `--exclude ${temporaryDeploymentDirectory}`
|
||||||
: ''
|
: ''
|
||||||
}`,
|
}`,
|
||||||
|
12
src/lib.ts
12
src/lib.ts
@ -1,7 +1,12 @@
|
|||||||
import {exportVariable, info, setFailed} from '@actions/core'
|
import {exportVariable, info, setFailed} from '@actions/core'
|
||||||
import {action, ActionInterface, Status} from './constants'
|
import {action, ActionInterface, Status} from './constants'
|
||||||
import {deploy, init} from './git'
|
import {deploy, init} from './git'
|
||||||
import {generateRepositoryPath, generateTokenType} from './util'
|
import {
|
||||||
|
generateFolderPath,
|
||||||
|
checkParameters,
|
||||||
|
generateRepositoryPath,
|
||||||
|
generateTokenType
|
||||||
|
} from './util'
|
||||||
|
|
||||||
/** Initializes and runs the action.
|
/** Initializes and runs the action.
|
||||||
*
|
*
|
||||||
@ -30,6 +35,11 @@ export default async function run(
|
|||||||
...configuration
|
...configuration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Defines the folder paths
|
||||||
|
settings.folderPath = generateFolderPath(settings)
|
||||||
|
|
||||||
|
checkParameters(settings)
|
||||||
|
|
||||||
// Defines the repository paths and token types.
|
// Defines the repository paths and token types.
|
||||||
settings.repositoryPath = generateRepositoryPath(settings)
|
settings.repositoryPath = generateRepositoryPath(settings)
|
||||||
settings.tokenType = generateTokenType(settings)
|
settings.tokenType = generateTokenType(settings)
|
||||||
|
43
src/util.ts
43
src/util.ts
@ -1,6 +1,7 @@
|
|||||||
|
import {existsSync} from 'fs'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import {isDebug} from '@actions/core'
|
import {isDebug} from '@actions/core'
|
||||||
import {ActionInterface, ActionFolders} from './constants'
|
import {ActionInterface, RequiredActionParameters} from './constants'
|
||||||
|
|
||||||
const replaceAll = (input: string, find: string, replace: string): string =>
|
const replaceAll = (input: string, find: string, replace: string): string =>
|
||||||
input.split(find).join(replace)
|
input.split(find).join(replace)
|
||||||
@ -28,40 +29,46 @@ export const generateRepositoryPath = (action: ActionInterface): string =>
|
|||||||
}@github.com/${action.repositoryName}.git`
|
}@github.com/${action.repositoryName}.git`
|
||||||
|
|
||||||
/* Genetate absolute folder path by the provided folder name */
|
/* Genetate absolute folder path by the provided folder name */
|
||||||
export const generateFolderPath = <K extends keyof ActionFolders>(
|
export const generateFolderPath = (action: ActionInterface): string => {
|
||||||
action: ActionInterface,
|
const folderName = action['folder']
|
||||||
key: K
|
return path.isAbsolute(folderName)
|
||||||
): string => {
|
|
||||||
const folderName = action[key]
|
|
||||||
const folderPath = path.isAbsolute(folderName)
|
|
||||||
? folderName
|
? folderName
|
||||||
: folderName.startsWith('~')
|
: folderName.startsWith('~')
|
||||||
? folderName.replace('~', process.env.HOME as string)
|
? folderName.replace('~', process.env.HOME as string)
|
||||||
: path.join(action.workspace, folderName)
|
: path.join(action.workspace, folderName)
|
||||||
return folderPath
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Checks for the required tokens and formatting. Throws an error if any case is matched. */
|
/* Checks for the required tokens and formatting. Throws an error if any case is matched. */
|
||||||
export const hasRequiredParameters = (action: ActionInterface): void => {
|
const hasRequiredParameters = <K extends keyof RequiredActionParameters>(
|
||||||
if (
|
action: ActionInterface,
|
||||||
(isNullOrUndefined(action.accessToken) &&
|
params: K[]
|
||||||
isNullOrUndefined(action.gitHubToken) &&
|
): boolean => {
|
||||||
isNullOrUndefined(action.ssh)) ||
|
const nonNullParams = params.filter(
|
||||||
isNullOrUndefined(action.repositoryPath) ||
|
param => !isNullOrUndefined(action[param])
|
||||||
(action.accessToken && action.accessToken === '')
|
)
|
||||||
) {
|
return Boolean(nonNullParams.length)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const checkParameters = (action: ActionInterface): void => {
|
||||||
|
if (!hasRequiredParameters(action, ['accessToken', 'gitHubToken', 'ssh'])) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'No deployment token/method was provided. You must provide the action with either a Personal Access Token or the GitHub Token secret in order to deploy. If you wish to use an ssh deploy token then you must set SSH to true.'
|
'No deployment token/method was provided. You must provide the action with either a Personal Access Token or the GitHub Token secret in order to deploy. If you wish to use an ssh deploy token then you must set SSH to true.'
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isNullOrUndefined(action.branch)) {
|
if (!hasRequiredParameters(action, ['branch'])) {
|
||||||
throw new Error('Branch is required.')
|
throw new Error('Branch is required.')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!action.folder || isNullOrUndefined(action.folder)) {
|
if (!hasRequiredParameters(action, ['folder'])) {
|
||||||
throw new Error('You must provide the action with a folder to deploy.')
|
throw new Error('You must provide the action with a folder to deploy.')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!existsSync(action.folderPath as string)) {
|
||||||
|
throw new Error(
|
||||||
|
`The ${action.folderPath} directory you're trying to deploy doesn't exist. ❗`
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Suppresses sensitive information from being exposed in error messages. */
|
/* Suppresses sensitive information from being exposed in error messages. */
|
||||||
|
Loading…
Reference in New Issue
Block a user