Skip to content

Commit

Permalink
πŸ› Make repo, user and branch url safe (#289)
Browse files Browse the repository at this point in the history
* fix: slugify repo and branch

* chore: linting

* fix: param case user

* chore: comment

* chore: comment

* chore: formatting

* feat: output unique deployment url

* fix: get deployment url with protocol

* feat: handle long branch urls

* feat: add logging

* chore: debug

* feat: logs

* fix: must be 63 chars

* fix: b64url

* fix: b64url

* fix: digest to hex

* chore: info to warning

* chore: remove editorconfig and prettier file

* chore: update lockfile

* chore: add back action-input-parser

* chore: improve regex

* chore: cleanup

---------

Co-authored-by: Josh Barr <[email protected]>
  • Loading branch information
Michael Bahr and Josh Barr authored Mar 16, 2023
1 parent 39ad2e1 commit 643bc80
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 18 deletions.
2 changes: 2 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ outputs:
description: 'True if a comment was created on the PR or commit.'
DEPLOYMENT_INSPECTOR_URL:
description: 'Main deployment inspection url.'
DEPLOYMENT_UNIQUE_URL:
description: 'The unique deployment url on Vercel'

runs:
using: 'node16'
Expand Down
49 changes: 40 additions & 9 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16550,6 +16550,7 @@ const core = __nccwpck_require__(2186)
const Github = __nccwpck_require__(8396)
const Vercel = __nccwpck_require__(847)
const { addSchema } = __nccwpck_require__(8505)
const crypto = __nccwpck_require__(6113)

const {
GITHUB_DEPLOYMENT,
Expand All @@ -16571,6 +16572,9 @@ const {
ACTOR
} = __nccwpck_require__(4570)

// Following https://perishablepress.com/stop-using-unsafe-characters-in-urls/ only allow characters that won't break the URL.
const urlSafeParameter = (input) => input.replace(/[^a-z0-9_~]/gi, '-')

const run = async () => {
const github = Github.init()

Expand Down Expand Up @@ -16616,27 +16620,53 @@ const run = async () => {
if (IS_PR && PR_PREVIEW_DOMAIN) {
core.info(`Assigning custom preview domain to PR`)

const alias = PR_PREVIEW_DOMAIN
.replace('{USER}', USER)
.replace('{REPO}', REPOSITORY)
.replace('{BRANCH}', BRANCH)
if (typeof PR_PREVIEW_DOMAIN !== 'string') {
throw new Error(`invalid type for PR_PREVIEW_DOMAIN`)
}

const alias = PR_PREVIEW_DOMAIN.replace('{USER}', urlSafeParameter(USER))
.replace('{REPO}', urlSafeParameter(REPOSITORY))
.replace('{BRANCH}', urlSafeParameter(BRANCH))
.replace('{PR}', PR_NUMBER)
.replace('{SHA}', SHA.substring(0, 7))
.toLowerCase()

await vercel.assignAlias(alias)
const previewDomainSuffix = '.vercel.app'
let nextAlias = alias


if (alias.endsWith(previewDomainSuffix)) {
let prefix = alias.substring(0, alias.indexOf(previewDomainSuffix))

if (prefix.length >= 60) {
core.warning(`The alias ${ prefix } exceeds 60 chars in length, truncating using vercel's rules. See https://vercel.com/docs/concepts/deployments/automatic-urls#automatic-branch-urls`)
prefix = prefix.substring(0, 55)
const uniqueSuffix = crypto.createHash('sha256')
.update(`git-${ BRANCH }-${ REPOSITORY }`)
.digest('hex')
.slice(0, 6)

deploymentUrls.push(addSchema(alias))
nextAlias = `${ prefix }-${ uniqueSuffix }${ previewDomainSuffix }`
core.info(`Updated domain alias: ${ nextAlias }`)
}
}

await vercel.assignAlias(nextAlias)
deploymentUrls.push(addSchema(nextAlias))
}

if (!IS_PR && ALIAS_DOMAINS) {
core.info(`Assigning custom domains to Vercel deployment`)

if (!Array.isArray(ALIAS_DOMAINS)) {
throw new Error(`invalid type for PR_PREVIEW_DOMAIN`)
}

for (let i = 0; i < ALIAS_DOMAINS.length; i++) {
const alias = ALIAS_DOMAINS[i]
.replace('{USER}', USER)
.replace('{REPO}', REPOSITORY)
.replace('{BRANCH}', BRANCH)
.replace('{USER}', urlSafeParameter(USER))
.replace('{REPO}', urlSafeParameter(REPOSITORY))
.replace('{BRANCH}', urlSafeParameter(BRANCH))
.replace('{SHA}', SHA.substring(0, 7))
.toLowerCase()

Expand Down Expand Up @@ -16702,6 +16732,7 @@ const run = async () => {

core.setOutput('PREVIEW_URL', previewUrl)
core.setOutput('DEPLOYMENT_URLS', deploymentUrls)
core.setOutput('DEPLOYMENT_UNIQUE_URL', deploymentUrls[deploymentUrls.length - 1])
core.setOutput('DEPLOYMENT_ID', deployment.id)
core.setOutput('DEPLOYMENT_INSPECTOR_URL', deployment.inspectorUrl)
core.setOutput('DEPLOYMENT_CREATED', true)
Expand Down
49 changes: 40 additions & 9 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const core = require('@actions/core')
const Github = require('./github')
const Vercel = require('./vercel')
const { addSchema } = require('./helpers')
const crypto = require('crypto')

const {
GITHUB_DEPLOYMENT,
Expand All @@ -23,6 +24,9 @@ const {
ACTOR
} = require('./config')

// Following https://perishablepress.com/stop-using-unsafe-characters-in-urls/ only allow characters that won't break the URL.
const urlSafeParameter = (input) => input.replace(/[^a-z0-9_~]/gi, '-')

const run = async () => {
const github = Github.init()

Expand Down Expand Up @@ -68,27 +72,53 @@ const run = async () => {
if (IS_PR && PR_PREVIEW_DOMAIN) {
core.info(`Assigning custom preview domain to PR`)

const alias = PR_PREVIEW_DOMAIN
.replace('{USER}', USER)
.replace('{REPO}', REPOSITORY)
.replace('{BRANCH}', BRANCH)
if (typeof PR_PREVIEW_DOMAIN !== 'string') {
throw new Error(`invalid type for PR_PREVIEW_DOMAIN`)
}

const alias = PR_PREVIEW_DOMAIN.replace('{USER}', urlSafeParameter(USER))
.replace('{REPO}', urlSafeParameter(REPOSITORY))
.replace('{BRANCH}', urlSafeParameter(BRANCH))
.replace('{PR}', PR_NUMBER)
.replace('{SHA}', SHA.substring(0, 7))
.toLowerCase()

await vercel.assignAlias(alias)
const previewDomainSuffix = '.vercel.app'
let nextAlias = alias


if (alias.endsWith(previewDomainSuffix)) {
let prefix = alias.substring(0, alias.indexOf(previewDomainSuffix))

deploymentUrls.push(addSchema(alias))
if (prefix.length >= 60) {
core.warning(`The alias ${ prefix } exceeds 60 chars in length, truncating using vercel's rules. See https://vercel.com/docs/concepts/deployments/automatic-urls#automatic-branch-urls`)
prefix = prefix.substring(0, 55)
const uniqueSuffix = crypto.createHash('sha256')
.update(`git-${ BRANCH }-${ REPOSITORY }`)
.digest('hex')
.slice(0, 6)

nextAlias = `${ prefix }-${ uniqueSuffix }${ previewDomainSuffix }`
core.info(`Updated domain alias: ${ nextAlias }`)
}
}

await vercel.assignAlias(nextAlias)
deploymentUrls.push(addSchema(nextAlias))
}

if (!IS_PR && ALIAS_DOMAINS) {
core.info(`Assigning custom domains to Vercel deployment`)

if (!Array.isArray(ALIAS_DOMAINS)) {
throw new Error(`invalid type for PR_PREVIEW_DOMAIN`)
}

for (let i = 0; i < ALIAS_DOMAINS.length; i++) {
const alias = ALIAS_DOMAINS[i]
.replace('{USER}', USER)
.replace('{REPO}', REPOSITORY)
.replace('{BRANCH}', BRANCH)
.replace('{USER}', urlSafeParameter(USER))
.replace('{REPO}', urlSafeParameter(REPOSITORY))
.replace('{BRANCH}', urlSafeParameter(BRANCH))
.replace('{SHA}', SHA.substring(0, 7))
.toLowerCase()

Expand Down Expand Up @@ -154,6 +184,7 @@ const run = async () => {

core.setOutput('PREVIEW_URL', previewUrl)
core.setOutput('DEPLOYMENT_URLS', deploymentUrls)
core.setOutput('DEPLOYMENT_UNIQUE_URL', deploymentUrls[deploymentUrls.length - 1])
core.setOutput('DEPLOYMENT_ID', deployment.id)
core.setOutput('DEPLOYMENT_INSPECTOR_URL', deployment.inspectorUrl)
core.setOutput('DEPLOYMENT_CREATED', true)
Expand Down

0 comments on commit 643bc80

Please sign in to comment.