New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(cli): cloud cli commands (v4) #20119
base: develop
Are you sure you want to change the base?
Conversation
packages/core/strapi/src/commands/actions/cloud/create-project/action.ts
Outdated
Show resolved
Hide resolved
packages/core/strapi/src/commands/actions/cloud/deploy-project/action.ts
Outdated
Show resolved
Hide resolved
packages/core/strapi/src/commands/actions/cloud/deploy-project/action.ts
Outdated
Show resolved
Hide resolved
packages/core/strapi/src/commands/actions/cloud/deploy-project/action.ts
Outdated
Show resolved
Hide resolved
packages/core/strapi/src/commands/actions/cloud/deploy-project/action.ts
Outdated
Show resolved
Hide resolved
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
packages/core/strapi/src/commands/actions/cloud/deploy-project/action.ts
Outdated
Show resolved
Hide resolved
packages/core/strapi/src/commands/actions/cloud/create-project/action.ts
Outdated
Show resolved
Hide resolved
b544834
to
eaed54e
Compare
eaed54e
to
42d0785
Compare
755dda4
to
3a2e3f9
Compare
Co-authored-by: Ben Irvin <ben.irvin@strapi.io>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks good 👍
A nice improvement would be to add the "deploy" in the generate package.json script so you can run
yarn deploy, & add it in the log at the end of the creation CLI
import { env } from '@strapi/utils'; | ||
|
||
export const apiConfig = { | ||
apiBaseUrl: env('STRAPI_CLI_CLOUD_API', 'https://cli.cloud.strapi.io'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
side note: libraries should avoid using env vars and get that as an input param unless it's a debug env var
Considering this will be just a way to test we can live with it. @innerdvations wdyt of a specific prefix for all hardcoded env var ? STRAPI_DEBUG
🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds fine to me. STRAPI_
will already be reserved for us, so if we want to call STRAPI_DEBUG_
the debugging prefix it won't cause any issues.
export function getTmpStoragePath() { | ||
const storagePath = path.join(os.tmpdir(), APP_FOLDER_NAME); | ||
if (!checkDirectoryExists(storagePath)) { | ||
fs.mkdirSync(storagePath, { recursive: true }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we use fs-extra everywhere in the codebase you could use the ensure fn directly
} | ||
|
||
function getConfigPath() { | ||
const configDirs = XDGAppPaths(APP_FOLDER_NAME).configDirs(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what would be the advantage ? we are not storing a pwd but just a temp access token 🤔
side note, Also this CLI could be used to automate deployment so we need to support tokens via the CLI in the CI.
} | ||
} | ||
|
||
export function saveLocalConfig(data: LocalConfig) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make all those file manipulation async instead ?
case 403: | ||
logger.error( | ||
error.response.data || | ||
'You do not have permission to create a project. Please contact support for assistance.' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in what case would you get a forbidden considering we do not really have an authorization system ?
project?: ProjectInfos; | ||
}; | ||
|
||
export function save(data: LocalSave, { directoryPath }: { directoryPath?: string } = {}) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment on using async fs methods instead
@@ -0,0 +1,43 @@ | |||
import chalk from 'chalk'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a //TODO to remove the duplicated code later with a share CLI pkg or sth
This should definitely be part of the CLI context passed to all commands 👍 but it goes beyond that as a topic for the CLI API overall |
} | ||
|
||
function getConfigPath() { | ||
const configDirs = XDGAppPaths(APP_FOLDER_NAME).configDirs(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would allow the user control the security level on the token and keeps it encrypted.
For example, I think most systems would allow users to configure their keychain to ask for verification before the token is accessed (so, someone sitting down at their system couldn't deploy without re-entering password/fingerprint/whatever). But I think what we're doing here is still secure enough for most cases.
I do think a separation by project would be extremely helpful though, otherwise someone with multiple clients on Strapi cloud would have to log in and out between each project, or accidentally attempt to deploy a project with the wrong account (though I assume it wouldn't work).
Alternatively, a login manager to switch between them, but that's a huge feature in itself 😆
import { isIgnoredFile } from '../compress-files'; | ||
|
||
describe('isIgnoredFile', () => { | ||
const folderPath = os.tmpdir(); // Use the system's temporary directory as a dummy folder path |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could use mock-fs here to avoid real effects in the test runs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fyi we use memfs already
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yeah, that one, I misremembered which one we used 😆
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor feedback
packages/cli/cloud/README.md
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shall we document here what commands are available?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes me think, don't we have in the contrbiuting guide the CLI command list too ? worth it if the others are listed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
); | ||
return; | ||
case 400: | ||
logger.error('Invalid input. Please check your inputs and try again.'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can improve this error message, it's really vague. Do you not return a good error message from the API you can utilise?
} | ||
} | ||
logger.error( | ||
'We encountered an issue while creating your project. Please try again in a moment. If the problem persists, contact support for assistance.' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should you propose using the debug
flag to find more info?
|
||
logger.debug(JSON.stringify(error)); | ||
if (error instanceof AxiosError) { | ||
switch (error.response?.status) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's 5XX should we handle it to show it's our problem not theres? at the moment it's not clear imo
ctx.logger.log('📦 Project compressed successfully!'); | ||
} catch (error: unknown) { | ||
ctx.logger.error( | ||
'⚠️ Project compression failed. Try again later or check for large/incompatible files.' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why would trying again later do anything different here?
ctx.logger.error(error.response.data); | ||
} | ||
} else { | ||
ctx.logger.error('An error occurred while deploying the project. Please try again later.'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we propose individuals use the debug
option to learn more about their issue?
import * as path from 'path'; | ||
import { minimatch } from 'minimatch'; | ||
|
||
const IGNORED_PATTERNS = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why blocklist over allowlist? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Allowing custom user code / resources
What does it do?
This pull request introduces new commands to the Strapi CLI for interacting with Strapi Cloud:
strapi login
: This command allows users to log in to their Strapi Cloud application directly from the command line.strapi logout
: This command enables users to log out of their currently authenticated Strapi Cloud session.strapi deploy
: This command provides a streamlined way to deploy the local Strapi project directly to Strapi Cloud.These functionalities aim to enhance the developer experience by simplifying authentication and deployment workflows for Strapi Cloud users and providing a seamless hosting solution for Strapi CMS users.
Important Update to create-strapi-app CLI:
Previously, when creating a new Strapi project using create-strapi-app, there was no option to directly connect to a Strapi Cloud project. This pull request also introduces changes to the create-strapi-app command. Users will now be prompted during project creation if they want to create and log in to a new Strapi Cloud project. This simplifies the workflow for developers who intend to deploy their Strapi project to Strapi Cloud from the very beginning.
Why is it needed?
Streamlining deployments: The deploy command automates the deployment process, allowing developers to push their local project to Strapi Cloud directly from the CLI.
How to test it?
strapi login
command to authenticate with your Strapi Cloud account. You'll likely be prompted for your credentials during this process (Google / GitHub or GitLab login providers ATM).strapi deploy
command to deploy your project to Strapi Cloud. Verify that the deployment process was completed successfully and your application is accessible on Strapi Cloud.strapi logout
command to disconnect the CLI from your Strapi Cloud account. Thestrapi deploy
should not work after being logged out.Related issue(s)/PR(s)
Let us know if this is related to any issue/pull request