Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 26 additions & 13 deletions src/commands/deploy.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { defineCommand, runCommand } from 'citty'
import { join, resolve, relative } from 'pathe'
import { execa } from 'execa'
import { setupDotenv } from 'c12'
import { $api, fetchUser, selectTeam, selectProject, projectPath, fetchProject, linkProject, gitInfo } from '../utils/index.mjs'
import { $api, fetchUser, selectTeam, selectProject, projectPath, fetchProject, linkProject, gitInfo, determineEnvironment } from '../utils/index.mjs'
import { getStorage, getPathsToDeploy, getFile, uploadAssetsToCloudflare, uploadWorkersAssetsToCloudflare, isMetaPath, isWorkerMetaPath, isServerPath, isWorkerServerPath, getPublicFiles, getWorkerPublicFiles } from '../utils/deploy.mjs'
import { createMigrationsTable, fetchRemoteMigrations, queryDatabase } from '../utils/database.mjs'
import login from './login.mjs'
Expand Down Expand Up @@ -40,6 +40,11 @@ export default defineCommand({
description: 'Force the current deployment as preview.',
default: false
},
env: {
type: 'string',
description: 'Force the environment of the current deployment. Available for Workers projects only.',
default: ''
},
dotenv: {
type: 'string',
description: 'Point to another .env file to load, relative to the root directory.',
Expand Down Expand Up @@ -92,6 +97,7 @@ export default defineCommand({
// Default to main branch
git.branch = git.branch || 'main'
let deployEnv = git.branch === linkedProject.productionBranch ? 'production' : 'preview'

if (args.production) {
git.branch = linkedProject.productionBranch
deployEnv = 'production'
Expand All @@ -100,21 +106,20 @@ export default defineCommand({
git.branch += '-preview'
}
deployEnv = 'preview'
} else if (linkedProject.type === 'worker' && args.env) {
deployEnv = args.env
} else if (linkedProject.type === 'worker' && git.branch !== linkedProject.productionBranch) {
deployEnv = await determineEnvironment(linkedProject.teamSlug, linkedProject.slug, git.branch)
}
const deployEnvColored = deployEnv === 'production' ? colors.greenBright(deployEnv) : colors.yellowBright(deployEnv)

const deployEnvColored = deployEnv === 'production'
? colors.greenBright(deployEnv)
: deployEnv === 'preview'
? colors.yellowBright(deployEnv)
: colors.blueBright(deployEnv) // additional environments
consola.success(`Connected to ${colors.blueBright(linkedProject.teamSlug)} team.`)
consola.success(`Linked to ${colors.blueBright(linkedProject.slug)} project.`)

if (linkedProject.type === 'worker' && deployEnv === 'preview') {
consola.warn('Currently NuxtHub on Workers (BETA) does not support preview environments.')
const shouldDeploy = await confirm({
message: `Deploy ${colors.blueBright(projectPath())} to production instead?`
})
if (!shouldDeploy || isCancel(shouldDeploy)) {
return consola.log('Cancelled.')
}
}

// #region Build
if (args.build) {
consola.info('Building the Nuxt project...')
Expand All @@ -125,7 +130,15 @@ export default defineCommand({
if (args.dotenv) {
nuxiBuildArgs.push(`--dotenv=${args.dotenv}`)
}
await execa({ stdio: 'inherit', preferLocal: true, cwd, extendEnv: false, env: {} })`nuxi build ${nuxiBuildArgs}`
await execa({
stdio: 'inherit',
preferLocal: true,
cwd,
extendEnv: false,
env: {
REMOTE_PROJECT_TYPE: linkedProject.type === 'worker' ? 'workers' : 'pages'
}
})`nuxi build ${nuxiBuildArgs}`
.catch((err) => {
if (err.code === 'ENOENT') {
consola.error('`nuxt` is not installed, please make sure that you are inside a Nuxt project.')
Expand Down
2 changes: 1 addition & 1 deletion src/utils/data.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ export async function selectProject(team) {
message: 'Select your project type',
initialValue: 'pages',
options: [
{ label: 'Cloudflare Workers', value: 'worker' },
{ label: 'Cloudflare Pages', value: 'pages' },
{ label: 'Cloudflare Workers (beta)', value: 'worker' },
]
})
if (isCancel(projectType)) return null
Expand Down
23 changes: 22 additions & 1 deletion src/utils/deploy.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import { ofetch } from 'ofetch'
import { createStorage } from 'unstorage'
import fsDriver from 'unstorage/drivers/fs'
import mime from 'mime'
import { withTilde, MAX_ASSET_SIZE, MAX_UPLOAD_CHUNK_SIZE, MAX_UPLOAD_ATTEMPTS, UPLOAD_RETRY_DELAY, CONCURRENT_UPLOADS } from './index.mjs'
import { withTilde, MAX_ASSET_SIZE, MAX_UPLOAD_CHUNK_SIZE, MAX_UPLOAD_ATTEMPTS, UPLOAD_RETRY_DELAY, CONCURRENT_UPLOADS, $api } from './index.mjs'
import prettyBytes from 'pretty-bytes'
import { gzipSize as getGzipSize } from 'gzip-size'
import { consola } from 'consola'

export function hashFile(filePath, data) {
const extension = extname(filePath).substring(1)
Expand Down Expand Up @@ -273,3 +274,23 @@ export async function uploadWorkersAssetsToCloudflare(accountId, files, cloudfla
}
return completionToken
}

/**
* Determine the deployment environment based on the branch name for Workers projects
* @param {string} teamSlug - The team slug
* @param {string} projectSlug - The project slug
* @param {string} branch - The git branch name
* @returns {Promise<string>} The determined environment name
*/
export async function determineEnvironment(teamSlug, projectSlug, branch) {
try {
const result = await $api(`/teams/${teamSlug}/projects/${projectSlug}/deploy/environment?branch=${branch}`, {
method: 'GET'
})
return result.name
} catch (error) {
// If API call fails, default to preview
consola.error('Failed to determine environment:', error)
process.exit(1)
}
}