Skip to content

Conversation

@kddejong
Copy link

  • Add comprehensive CloudFormation Language Server Protocol support
  • Include CloudFormation explorer with stack management capabilities
  • Add stack deployment, validation, and change set workflows
  • Include SageMaker UX improvements and Amazon Q inline notifications
  • Update package dependencies and configurations

Problem

Solution


  • Treat all work as PUBLIC. Private feature/x branches will not be squash-merged at release time.
  • Your code changes must meet the guidelines in CONTRIBUTING.md.
  • License: I confirm that my contribution is made under the terms of the Apache 2.0 license.

@kddejong kddejong requested a review from a team as a code owner November 10, 2025 01:52
@github-actions
Copy link

  • This pull request implements a feat or fix, so it must include a changelog entry (unless the fix is for an unreleased feature). Review the changelog guidelines.
    • Note: beta or "experiment" features that have active users should announce fixes in the changelog.
    • If this is not a feature or fix, use an appropriate type from the title guidelines. For example, telemetry-only changes should use the telemetry type.

- Add CloudFormation Language Server Protocol support with multiple provider options
- Include CloudFormation explorer with stack, resource, and change set management
- Add stack deployment, validation, and change set workflows with S3 upload support
- Include drift detection and diff visualization capabilities
- Add CloudFormation environment and project management with cfn-init integration
- Include telemetry and authentication handling
- Add comprehensive test coverage for all CloudFormation features
- Update package configurations and language syntax highlighting
@kddejong kddejong force-pushed the feature/cloudformation branch from f21322d to 09b66ad Compare November 10, 2025 01:53
Copy link
Contributor

@laileni-aws laileni-aws left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the next time,
can we please raise short PR at regular intervals which will be easy to review!

Reviewing 114 files and 13K+ lines of code is tough and time consuming!

Thank you.

return path.join(workspaceRoot, this.cfnProjectPath, this.environmentsDirectory, environmentName)
}

private async getConfigPath(): Promise<string> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we can move this to shared/utils

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will move to shared/utils

const result = await resourcesManager.searchResource(node.label as string, identifier)

if (result.found) {
void window.showInformationMessage(`Resource found: ${identifier}`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did we get sign off on these strings?
I guess we can be more elaborate on this information message or error message

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe our UX/Product has synced up with ToolKit team members to get confirmation on what we will show to customers

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you cross check on this ?
Thanks

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We received fit and finish approval today and this was one of the messages that was demonstrated. No issues raised.

import { CloudFormationExplorer } from '../explorer/explorer'
import { commandKey } from '../utils'

export function selectEnvironmentCommand(explorer: CloudFormationExplorer): vscode.Disposable {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need separate files for each command ? Instead we can have a single file like command.ts and include all commands inside and export them!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can consolidate to one commands file


const DocumentPreviewNotification = new NotificationType<DocumentPreviewType>('aws/document/preview')

export class DocumentPreview {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be shared utils function!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless other parts of ToolKit needs this feature, is it worth moving it to the shared/utils?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is commonly used to show the preview but not a blocker for sure

const message =
'Help us improve the AWS CloudFormation Language Server by sharing anonymous telemetry data with AWS. You can change this preference at any time in aws.cloudformation Settings.'

const allow = 'Yes, Allow'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can improve readability

const THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1000
const TELEMETRY_LEARN_MORE_URL = 'github.com/aws-cloudformation/cloudformation-languageserver/tree/main/src/telemetry'

interface TelemetryPromptOptions {
    allow: string
    later: string
    never: string
    learnMore: string
}

const PROMPT_OPTIONS: TelemetryPromptOptions = {
    allow: 'Yes, Allow',
    later: 'Not Now',
    never: 'Never',
    learnMore: 'Learn More'
}

const TELEMETRY_MESSAGE = 
    'Help us improve the AWS CloudFormation Language Server by sharing anonymous telemetry data with AWS. ' +
    'You can change this preference at any time in aws.cloudformation Settings.'
    ```

…ents

- Remove resource type from list using right click
- Few startup fixes for CloudFormation extension
- Add exec permissions and support node versions
- Add node to AWS Explorer CFN panel
- Add prompt for deploymentMode and plumb to deployment
- Coordinate stack views and add overview to CFN console
- Fix extract to parameter cursor command
…ents

* Remove resource type from list using right click
* Few startup fixes for CloudFormation extension
* Add exec permissions and support node versions
* Add node to AWS Explorer CFN panel
* Add prompt for deploymentMode and plumb to deployment
* Coordinate stack views and add overview to CFN console
* Fix extract to parameter cursor command
try {
const data = JSON.parse(context)
const pathParts = path.split('/').filter(Boolean)
let current: any = data
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:
Datatype is JSON

)?.value
}

export async function getImportExistingResources(): Promise<boolean | undefined> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we reuse above getIncludeNestedStacks function ?

if (nodeA instanceof AWSCommandTreeNode) {
return -1
}
if (nodeB instanceof AWSCommandTreeNode) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if ( nodeA instanceof AWSCommandTreeNode || nodeB instanceof AWSCommandTreeNode) {
     return 1
 }

label: 'test-profile',
state: 'valid',
} as any,
} as any
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dataType: sinon.SinonStubbedInstance

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will make updates to the tests

@@ -0,0 +1,4 @@
{
"type": "Feature",
"description": "CloudFormation: Add comprehensive Language Server Protocol integration with stack management, deployment workflows, drift detection, and cfn-init project support"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If required we can add multiple change logs.

Copy link
Contributor

@laileni-aws laileni-aws left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to work on some nits and code refactoring but NOT a blocker for RIV:2025

await this.updateCredentialsFromActiveConnection()
}

private async updateCredentialsFromActiveConnection(): Promise<void> {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will this always send the credentials or only when the feature is used?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its hard to say if the feature is being used, because there are a lot of just UI elements visualizing their resources. Which requires sending credentials to load, they might not interact with the UI other than just viewing.
This will send the credentials anytime it changes, as long as the LSP is active

}

public async getEnvironmentDir(environmentName: string): Promise<string> {
const workspaceRoot = workspace.workspaceFolders?.[0]?.uri.fsPath

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this can be moved to a util function

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will move to a util function

parametersFiles?: string[]
}

export class CfnInitCliCaller {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this calling a dependency?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the dependency is located inside the server code.

await progress
void vscode.window.showInformationMessage(`CFN project '${this.state.projectName}' created!`)

const openProject = await vscode.window.showQuickPick(['Yes', 'No'], {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this already have pre-existing functions?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No pre-existing functions for this case

try {
// Show sign-in message when not authenticated
if (!globals.awsContext.getCredentialProfileName()) {
const signInNode = new PlaceholderNode(this as any, 'Sign in to get started')

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would this allow all types of sign in?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this just uses the existing login workflow

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants