Skip to content

Commit

Permalink
Merge pull request #299 from github/lock-branch-validation
Browse files Browse the repository at this point in the history
Lock Branch Validation
  • Loading branch information
GrantBirki authored Aug 31, 2024
2 parents 7d3b7d8 + bada9d6 commit a40c82b
Show file tree
Hide file tree
Showing 9 changed files with 118 additions and 9 deletions.
53 changes: 53 additions & 0 deletions __tests__/functions/valid-branch-name.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import {constructValidBranchName} from '../../src/functions/valid-branch-name'
import * as core from '@actions/core'

const debugMock = jest.spyOn(core, 'debug')

const branchName = 'production'

beforeEach(() => {
jest.clearAllMocks()
jest.spyOn(core, 'debug').mockImplementation(() => {})
})

test('does not make any modifications to a valid branch name', async () => {
expect(constructValidBranchName(branchName)).toBe(branchName)
expect(debugMock).toHaveBeenCalledWith(
`constructing valid branch name: ${branchName}`
)
expect(debugMock).toHaveBeenCalledWith(
`constructed valid branch name: ${branchName}`
)
})

test('replaces spaces with hyphens', async () => {
expect(constructValidBranchName(`super ${branchName}`)).toBe(
`super-${branchName}`
)
expect(debugMock).toHaveBeenCalledWith(
`constructing valid branch name: super ${branchName}`
)
expect(debugMock).toHaveBeenCalledWith(
`constructed valid branch name: super-${branchName}`
)
})

test('replaces multiple spaces with hyphens', async () => {
expect(constructValidBranchName(`super duper ${branchName}`)).toBe(
`super-duper-${branchName}`
)
expect(debugMock).toHaveBeenCalledWith(
`constructing valid branch name: super duper ${branchName}`
)
expect(debugMock).toHaveBeenCalledWith(
`constructed valid branch name: super-duper-${branchName}`
)
})

test('returns null if the branch is null', async () => {
expect(constructValidBranchName(null)).toBe(null)
})

test('returns undefined if the branch is undefined', async () => {
expect(constructValidBranchName(undefined)).toBe(undefined)
})
37 changes: 33 additions & 4 deletions dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions src/functions/check-lock-file.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {LOCK_METADATA} from './lock-metadata'
import {COLORS} from './colors'
import {constructValidBranchName} from './valid-branch-name'
import * as core from '@actions/core'

const LOCK_FILE = LOCK_METADATA.lockFile
Expand All @@ -10,6 +11,8 @@ const LOCK_FILE = LOCK_METADATA.lockFile
// :param branchName: The name of the branch to check
// :return: The lock file contents if it exists, false if not
export async function checkLockFile(octokit, context, branchName) {
branchName = constructValidBranchName(branchName)

core.debug(`checking if lock file exists on branch: ${branchName}`)
// If the lock branch exists, check if a lock file exists
try {
Expand Down
3 changes: 2 additions & 1 deletion src/functions/lock.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as core from '@actions/core'
import dedent from 'dedent-js'
import {checkLockFile} from './check-lock-file'
import {actionStatus} from './action-status'
import {constructValidBranchName} from './valid-branch-name'
import {timeDiff} from './time-diff'
import {LOCK_METADATA} from './lock-metadata'
import {COLORS} from './colors'
Expand All @@ -23,7 +24,7 @@ async function constructBranchName(environment, global) {
}

// If the lock is not global, return the environment-specific lock branch name
return `${environment}-${LOCK_BRANCH_SUFFIX}`
return `${constructValidBranchName(environment)}-${LOCK_BRANCH_SUFFIX}`
}

// Helper function for creating a lock file for branch-deployment locks
Expand Down
3 changes: 2 additions & 1 deletion src/functions/unlock-on-merge.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as core from '@actions/core'
import {unlock} from './unlock'
import {LOCK_METADATA} from './lock-metadata'
import {checkLockFile} from './check-lock-file'
import {constructValidBranchName} from './valid-branch-name'

// Helper function to automatically find, and release a deployment lock when a pull request is merged
// :param octokit: the authenticated octokit instance
Expand All @@ -28,7 +29,7 @@ export async function unlockOnMerge(octokit, context, environment_targets) {
var releasedEnvironments = []
for (const environment of environment_targets.split(',')) {
// construct the lock branch name for this environment
var lockBranch = `${environment}-${LOCK_METADATA.lockBranchSuffix}`
var lockBranch = `${constructValidBranchName(environment)}-${LOCK_METADATA.lockBranchSuffix}`

// attempt to fetch the lockFile for this branch
var lockFile = await checkLockFile(octokit, context, lockBranch)
Expand Down
3 changes: 2 additions & 1 deletion src/functions/unlock.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as core from '@actions/core'
import {actionStatus} from './action-status'
import dedent from 'dedent-js'
import {LOCK_METADATA} from './lock-metadata'
import {constructValidBranchName} from './valid-branch-name'
import {COLORS} from './colors'

// Constants for the lock file
Expand Down Expand Up @@ -90,7 +91,7 @@ export async function unlock(
branchName = GLOBAL_LOCK_BRANCH
successText = '`global`'
} else {
branchName = `${environment}-${LOCK_BRANCH_SUFFIX}`
branchName = `${constructValidBranchName(environment)}-${LOCK_BRANCH_SUFFIX}`
successText = `\`${environment}\``
}

Expand Down
20 changes: 20 additions & 0 deletions src/functions/valid-branch-name.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import * as core from '@actions/core'

// Helper function to create a valid branch name that will pass GitHub's API ref validation
// :param branch: The branch name
// :returns: A string of the branch name with proper formatting
export function constructValidBranchName(branch) {
core.debug(`constructing valid branch name: ${branch}`)

if (branch === null) {
return null
} else if (branch === undefined) {
return undefined
}

// If environment contains any spaces, replace all of them with a hyphen
branch = branch.replace(/\s/g, '-')

core.debug(`constructed valid branch name: ${branch}`)
return branch
}
3 changes: 2 additions & 1 deletion src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {help} from './functions/help'
import {LOCK_METADATA} from './functions/lock-metadata'
import {COLORS} from './functions/colors'
import {getInputs} from './functions/inputs'
import {constructValidBranchName} from './functions/valid-branch-name'

// :returns: 'success', 'success - noop', 'success - merge deploy mode', 'failure', 'safe-exit', 'success - unlock on merge mode' or raises an error
export async function run() {
Expand Down Expand Up @@ -255,7 +256,7 @@ export async function run() {
// special comment for global deploy locks
let globalMsg = ''
let environmentMsg = `- __Environment__: \`${lockData.environment}\``
let lockBranchName = `${lockData.environment}-${LOCK_METADATA.lockBranchSuffix}`
let lockBranchName = `${constructValidBranchName(lockData.environment)}-${LOCK_METADATA.lockBranchSuffix}`
if (lockData.global === true) {
globalMsg = dedent(`
Expand Down

0 comments on commit a40c82b

Please sign in to comment.