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
10 changes: 6 additions & 4 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@ Please make sure to read the Pull Request Guidelines:
https://github.com/aws-amplify/amplify-cli/blob/dev/CONTRIBUTING.md#pull-requests
-->

#### Description of changes
### Description of changes

<!--
Thank you for your Pull Request! Please provide a description above and review
the requirements below.
-->

#### Issue #, if available
### Issue #, if available

<!-- Also, please reference any associated PRs for documentation updates. -->

#### Description of how you validated changes
### Description of how you validated changes

#### Checklist
### Checklist

<!-- Remove items that do not apply. For completed items, change [ ] to [x]. -->

Expand All @@ -27,4 +27,6 @@ the requirements below.
- [ ] New AWS SDK calls or CloudFormation actions have been added to relevant test and service IAM policies
- [ ] [Pull request labels](https://github.com/aws-amplify/amplify-cli/blob/dev/CONTRIBUTING.md#labels) are added

---

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,4 @@ amplify-migration-apps/**/_snapshot.*.actual*
.pr-body.ai-generated.md
.commit-message.ai-generated.txt
.kiro-session.ai-generated.md
**/.amplify/refactor.operations
**/.gen2-migration/refactor.operations
116 changes: 116 additions & 0 deletions .kiro/skills/gen2-migration/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
---
name: gen2-migration
description: Development guidance for the Amplify Gen1-to-Gen2 migration tooling — architecture, commands, testing, and snapshot workflows
---

# Gen2 Migration Development

This skill provides context for working on the `amplify gen2-migration` CLI feature,
which migrates Amplify Gen1 applications to Gen2.

## Context

### Documentation

Before changing code, read the relevant docs files. They are the source of truth
for architecture and design decisions:

| Doc | Covers |
| --------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| `docs/packages/amplify-cli/src/commands/gen2-migration.md` | Architecture, CLI interface, Plan lifecycle, subcommand design |
| `packages/amplify-gen2-migration-e2e-system/README.md` | E2E automation system, CLI options, migration workflow steps |
| `packages/amplify-cli/src/__tests__/commands/gen2-migration/_framework/README.md` | Test framework, mock clients, snapshot comparison, customization |
| https://docs.amplify.aws/gen1/react/tools/cli/ | Amplify Gen1 CLI documentation |
| https://docs.amplify.aws/react/build-a-backend/ | Amplify Gen2 backend documentation |

### Code

- `packages/amplify-cli/src/commands/gen2-migration/` — CLI commands and core logic
- `packages/amplify-cli/src/__tests__/commands/gen2-migration/` — Snapshot and unit tests
- `packages/amplify-gen2-migration-e2e-system/` — E2E testing automation

### Apps

Each subdirectory under `amplify-migration-apps/` is a test app representing a Gen1 project
with a specific combination of Amplify categories and configurations. See
`amplify-migration-apps/README.md` for the full structure and conventions.

## Development Loop

### Fix a Bug

The snapshot inputs (`_snapshot.pre.*`) don't change — only the code and possibly the
expected outputs (`_snapshot.post.*`) change.

1. Read the relevant Context above for the area you're touching.

2. Analyze the bug by reading the affected app's snapshot files. Read the
`_snapshot.pre.generate/` and/or `_snapshot.pre.refactor/` files to understand the
input configuration, and the `_snapshot.post.*` files to identify what's wrong in the
current output.

3. Reproduce the bug by running the appropriate E2E test:

```bash
cd amplify-migration-apps/<app-name>
npm run test:e2e
```

After the E2E run, inspect the live Gen1 and Gen2 resources and CloudFormation stack
events using the AWS CLI to confirm the root cause.

4. Present the root cause analysis to the user.

5. Determine what the correct expected output should be after the fix. Present the proposed
change to the expected output to the user and get approval before writing code.

6. Make the code change in `packages/amplify-cli/src/commands/gen2-migration/`.

7. Determine if the fix requires a new or updated E2E validation test in the affected app's
`tests/` directory. These tests run against deployed stacks to verify the migrated app
works correctly (API queries, storage operations, auth flows). See existing app tests
for the pattern (e.g., `amplify-migration-apps/project-boards/tests/`).

8. Ask the user for confirmation before running E2E tests — they take a long time and
require AWS credentials. If approved, run on the affected apps to regenerate snapshots:

```bash
cd amplify-migration-apps/<app-name>
UPDATE_SNAPSHOTS=1 npm run test:e2e
```

9. Run `yarn build && yarn test` in `packages/amplify-cli/` to verify nothing else broke.
If tests fail at this point, only test code changes should be needed — the production
code was already validated by the E2E run.

### Implement a New Feature

1. Read the relevant Context above for the area you're extending.

2. Read the existing test apps to find one that covers a similar configuration, or determine
that a new app is needed.

3. Follow the "Adding an App" or "Modifying an App" instructions from
`amplify-migration-apps/README.md` to update or create the `_snapshot.pre.generate/`
inputs. Skip the E2E step — we'll run it after making code changes.

4. Determine what the expected output should be. Present the proposed expected output to
the user and get approval before writing code.

5. Make the code change in `packages/amplify-cli/src/commands/gen2-migration/`.

6. Determine if the feature requires a new or updated E2E validation test in the affected
app's `tests/` directory. See existing app tests for the pattern
(e.g., `amplify-migration-apps/project-boards/tests/`).

7. Ask the user for confirmation before running E2E tests — they take a long time and
require AWS credentials. If approved, run on the affected apps to regenerate snapshots:

```bash
cd amplify-migration-apps/<app-name>
UPDATE_SNAPSHOTS=1 npm run test:e2e
```

8. Run `yarn build && yarn test` in `packages/amplify-cli/` to verify nothing else broke.
If tests fail at this point, only test code changes should be needed — the production
code was already validated by the E2E run.
2 changes: 2 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ When asked to create a PR, generate a body into `.pr-body.ai-generated.md` **at
- Do a 30 second summary of the important design information.
- Do not go overboard on technical details. A reviewer can read the code.
- Keep it concise and scannable.
- Don't enumerate files changed. Instead, categorize changes into logical groups. Give each
group an h4 title on its own line, followed by a blank line, then the explanation.

## Delegating to Sub-Agents

Expand Down
8 changes: 6 additions & 2 deletions amplify-migration-apps/.gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# Ignore amplify dirs created by `amplify init` at each app root,
# but not the ones inside _snapshot.* folders which are tracked.
# Ignore dirs created by amplify CLI commands.
*/amplify/
*/.gen2-migration/
*amplifyconfiguration.json
*amplify_outputs.json

# But not the ones inside _snapshot.* folders which are tracked and santized.
!*/_snapshot.*/amplify/
89 changes: 31 additions & 58 deletions amplify-migration-apps/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,17 +258,17 @@ directories from a deployed Amplify app. It requires AWS credentials with access
deployed app's CloudFormation stacks and Amplify resources.

```console
npx tsx snapshot.ts <step> <app-name> [deployed-app-path]
npx tsx snapshot.ts <step> <app-dir> [deployed-app-path] [gen2-stack-name]
```

Where `<step>` is one of:

| Step | Description | Requires `deployed-app-path`? |
| ---------------- | --------------------------------------------------------------------------- | ----------------------------- |
| `pre.generate` | Copies the Gen1 app's `amplify/`, `.gitignore`, and `package.json` | Yes |
| `post.generate` | Copies the Gen2 output (`amplify/`, `.gitignore`, `amplify.yml`) | Yes |
| `pre.refactor` | Downloads Gen1 and Gen2 CloudFormation templates from deployed stacks | No (reads from AWS directly) |
| `post.refactor` | Copies the refactor operations from `.amplify/refactor.operations` | Yes |
| Step | Description | Required args |
| ---------------- | --------------------------------------------------------------------------- | -------------------------------------- |
| `pre.generate` | Copies the Gen1 app's `amplify/`, `.gitignore`, and `package.json` | `deployed-app-path` |
| `post.generate` | Copies the Gen2 output (`amplify/`, `.gitignore`, `amplify.yml`) | `deployed-app-path` |
| `pre.refactor` | Downloads Gen1 and Gen2 CloudFormation templates from deployed stacks | `gen2-stack-name` |
| `post.refactor` | Copies the refactor operations from `.gen2-migration/refactor.operations` | `deployed-app-path` |

Examples:

Expand All @@ -280,57 +280,40 @@ npx tsx snapshot.ts pre.generate fitness-tracker /path/to/deployed/fitness-track
npx tsx snapshot.ts post.generate fitness-tracker /path/to/deployed/fitness-tracker

# Download CloudFormation templates for refactor input (requires AWS credentials)
npx tsx snapshot.ts pre.refactor fitness-tracker
npx tsx snapshot.ts pre.refactor fitness-tracker /path/to/deployed/fitness-tracker amplify-fitnesstracker-gen2main-branch-abc1234567

# Capture the expected refactor output
npx tsx snapshot.ts post.refactor fitness-tracker /path/to/deployed/fitness-tracker
```

## Adding an App

1. Create a new directory under `<app-name>` that contains the entire Gen1 application, as is.
2. Add the following script directives to the `package.json` file:

```json
"scripts": {
"sanitize": "tsx ../sanitize.ts",
"typecheck": "cd _snapshot.post.generate/amplify && npx tsc --noEmit"
}
```

3. Add the following to the `package.json` file:

```json
"installConfig": {
"hoistingLimits": "workspaces"
},
```

This ensures dependencies in the app don't interfere or conflict with the main repo dependencies.

4. Use the [Snapshot Capture Tool](#snapshot-capture-tool) to capture all required snapshots.
Follow the app's migration guide, running the tool at each step:
1. Create a new directory under `<app-name>` that contains the frontend code for your Gen1 application.
Make sure to follow the existing patterns and add tests as well.
2. Run `amplify init`.
3. Configure the backend using Gen1 CLI.
4. Run `amplify push`.
5. Use the [Snapshot Capture Tool](#snapshot-capture-tool) to capture the `pre.generate` snapshot.

```console
# Before running generate
npx tsx snapshot.ts pre.generate <app-name> /path/to/deployed/<app-name>

# After running generate
npx tsx snapshot.ts post.generate <app-name> /path/to/deployed/<app-name>
npx tsx snapshot.ts pre.generate <app-name>

# Before running refactor (requires AWS credentials)
npx tsx snapshot.ts pre.refactor <app-name>
6. Run `UPDATE_SNAPSHOTS=1 npm run test:e2e` to execute the full migration flow and capture
the remaining snapshots (`post.generate`, `pre.refactor`, `post.refactor`).

# After running refactor
npx tsx snapshot.ts post.refactor <app-name> /path/to/deployed/<app-name>
```
## Modifying an App

5. Run the sanitize script to replace sensitive values with placeholders:
1. `cd` into a specific app and run `npm run deploy`.
2. Locate the deployed app directory in output logs and `cd` into it.
3. Update the backend using Gen1 CLI.
4. Run `amplify push`.
5. Use the [Snapshot Capture Tool](#snapshot-capture-tool) to capture the `pre.generate` snapshot.

```console
cd amplify-migration-apps/<app-name>
npm run sanitize
```
npx tsx snapshot.ts pre.generate <app-name>

6. Run `UPDATE_SNAPSHOTS=1 npm run test:e2e` to execute the full migration flow and capture
the remaining snapshots (`post.generate`, `pre.refactor`, `post.refactor`).

## Snapshot Testing

Expand Down Expand Up @@ -426,7 +409,6 @@ Always review the diff after updating to make sure the changes are intentional.
> because it detects the diff before writing the updated files. Run the tests a second time
> (without `--updateSnapshot`) to verify the snapshots are now correct.


## Integration Testing (E2E)

The [E2E system](../packages/amplify-gen2-migration-e2e-system/) automates the full migration
Expand All @@ -441,19 +423,10 @@ cd packages/amplify-cli && yarn build
export AMPLIFY_PATH=$(pwd)/.bin/amplify-dev

# Run the full migration for a specific app
cd packages/amplify-gen2-migration-e2e-system
npx tsx src/cli.ts --app project-boards --profile default
cd amplify-migration-apps/<app-name>
npm run test:e2e
```

This will:
1. Deploy the Gen1 app via `amplify push`
2. Run `test:gen1` to validate the Gen1 stack
3. Execute the full `gen2-migration` workflow (assess, lock, generate, deploy, refactor, redeploy)
4. Run `test:gen1` and `test:gen2` after each deployment

The system automatically runs npm scripts from the app's `package.json` at the right
points in the workflow — `post-generate` after generate, `post-refactor` after refactor,
and `post-push` after push. Scripts that resolve to `true` (no-op) are effectively skipped.

See the [E2E system README](../packages/amplify-gen2-migration-e2e-system/README.md) for
CLI options and troubleshooting.
points in the workflow. See the [E2E system README](../packages/amplify-gen2-migration-e2e-system/README.md) for
more details.
1 change: 1 addition & 0 deletions amplify-migration-apps/backend-only/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"test:gen1": "true",
"test:gen2": "true",
"test:e2e": "cd ../../packages/amplify-gen2-migration-e2e-system && npx tsx src/cli.ts --app backend-only --profile ${AWS_PROFILE:-default}",
"deploy": "cd ../../packages/amplify-gen2-migration-e2e-system && npx tsx src/cli.ts --app backend-only --step deploy --profile ${AWS_PROFILE:-default}",
"pre-push": "true",
"post-generate": "npx tsx migration/post-generate.ts",
"post-refactor": "npx tsx migration/post-refactor.ts",
Expand Down
1 change: 1 addition & 0 deletions amplify-migration-apps/discussions/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"test:gen1": "APP_CONFIG_PATH=${APP_CONFIG_PATH:-src/amplifyconfiguration.json} NODE_OPTIONS='--experimental-vm-modules' jest --verbose",
"test:gen2": "APP_CONFIG_PATH=${APP_CONFIG_PATH:-amplify_outputs.json} NODE_OPTIONS='--experimental-vm-modules' jest --verbose",
"test:e2e": "cd ../../packages/amplify-gen2-migration-e2e-system && npx tsx src/cli.ts --app discussions --profile ${AWS_PROFILE:-default}",
"deploy": "cd ../../packages/amplify-gen2-migration-e2e-system && npx tsx src/cli.ts --app discussions --step deploy --profile ${AWS_PROFILE:-default}",
"pre-push": "true",
"post-generate": "npx tsx migration/post-generate.ts",
"post-refactor": "npx tsx migration/post-refactor.ts",
Expand Down
1 change: 1 addition & 0 deletions amplify-migration-apps/fitness-tracker/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"test:gen1": "APP_CONFIG_PATH=${APP_CONFIG_PATH:-src/amplifyconfiguration.json} NODE_OPTIONS='--experimental-vm-modules' jest --verbose",
"test:gen2": "APP_CONFIG_PATH=${APP_CONFIG_PATH:-amplify_outputs.json} NODE_OPTIONS='--experimental-vm-modules' jest --verbose",
"test:e2e": "cd ../../packages/amplify-gen2-migration-e2e-system && npx tsx src/cli.ts --app fitness-tracker --profile ${AWS_PROFILE:-default}",
"deploy": "cd ../../packages/amplify-gen2-migration-e2e-system && npx tsx src/cli.ts --app fitness-tracker --step deploy --profile ${AWS_PROFILE:-default}",
"pre-push": "true",
"post-generate": "npx tsx migration/post-generate.ts",
"post-refactor": "true",
Expand Down
1 change: 1 addition & 0 deletions amplify-migration-apps/imported-resources/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"test:gen1": "APP_CONFIG_PATH=${APP_CONFIG_PATH:-src/amplifyconfiguration.json} NODE_OPTIONS='--experimental-vm-modules' jest --verbose",
"test:gen2": "APP_CONFIG_PATH=${APP_CONFIG_PATH:-amplify_outputs.json} NODE_OPTIONS='--experimental-vm-modules' jest --verbose",
"test:e2e": "cd ../../packages/amplify-gen2-migration-e2e-system && npx tsx src/cli.ts --app imported-resources --profile ${AWS_PROFILE:-default}",
"deploy": "cd ../../packages/amplify-gen2-migration-e2e-system && npx tsx src/cli.ts --app imported-resources --step deploy --profile ${AWS_PROFILE:-default}",
"pre-push": "true",
"post-generate": "npx tsx migration/post-generate.ts",
"post-refactor": "npx tsx migration/post-refactor.ts",
Expand Down
1 change: 1 addition & 0 deletions amplify-migration-apps/media-vault/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"test:gen1": "APP_CONFIG_PATH=${APP_CONFIG_PATH:-src/amplifyconfiguration.json} NODE_OPTIONS='--experimental-vm-modules' jest --verbose",
"test:gen2": "APP_CONFIG_PATH=${APP_CONFIG_PATH:-amplify_outputs.json} NODE_OPTIONS='--experimental-vm-modules' jest --verbose",
"test:e2e": "cd ../../packages/amplify-gen2-migration-e2e-system && npx tsx src/cli.ts --app media-vault --profile ${AWS_PROFILE:-default}",
"deploy": "cd ../../packages/amplify-gen2-migration-e2e-system && npx tsx src/cli.ts --app media-vault --step deploy --profile ${AWS_PROFILE:-default}",
"pre-push": "npx tsx migration/pre-push.ts",
"post-generate": "npx tsx migration/post-generate.ts",
"post-refactor": "true",
Expand Down
1 change: 1 addition & 0 deletions amplify-migration-apps/mood-board/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"test:gen1": "APP_CONFIG_PATH=${APP_CONFIG_PATH:-src/amplifyconfiguration.json} NODE_OPTIONS='--experimental-vm-modules' jest --verbose",
"test:gen2": "APP_CONFIG_PATH=${APP_CONFIG_PATH:-amplify_outputs.json} NODE_OPTIONS='--experimental-vm-modules' jest --verbose",
"test:e2e": "cd ../../packages/amplify-gen2-migration-e2e-system && npx tsx src/cli.ts --app mood-board --profile ${AWS_PROFILE:-default}",
"deploy": "cd ../../packages/amplify-gen2-migration-e2e-system && npx tsx src/cli.ts --app mood-board --step deploy --profile ${AWS_PROFILE:-default}",
"pre-push": "true",
"post-generate": "npx tsx migration/post-generate.ts",
"post-refactor": "npx tsx migration/post-refactor.ts",
Expand Down
1 change: 1 addition & 0 deletions amplify-migration-apps/product-catalog/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"test:gen1": "APP_CONFIG_PATH=${APP_CONFIG_PATH:-src/amplifyconfiguration.json} NODE_OPTIONS='--experimental-vm-modules' jest --verbose",
"test:gen2": "APP_CONFIG_PATH=${APP_CONFIG_PATH:-amplify_outputs.json} NODE_OPTIONS='--experimental-vm-modules' jest --verbose",
"test:e2e": "cd ../../packages/amplify-gen2-migration-e2e-system && npx tsx src/cli.ts --app product-catalog --profile ${AWS_PROFILE:-default}",
"deploy": "cd ../../packages/amplify-gen2-migration-e2e-system && npx tsx src/cli.ts --app product-catalog --step deploy --profile ${AWS_PROFILE:-default}",
"pre-push": "npx tsx migration/pre-push.ts",
"post-generate": "npx tsx migration/post-generate.ts",
"post-refactor": "npx tsx migration/post-refactor.ts",
Expand Down
1 change: 1 addition & 0 deletions amplify-migration-apps/project-boards/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"test:gen1": "APP_CONFIG_PATH=${APP_CONFIG_PATH:-src/amplifyconfiguration.json} NODE_OPTIONS='--experimental-vm-modules' jest --verbose",
"test:gen2": "APP_CONFIG_PATH=${APP_CONFIG_PATH:-amplify_outputs.json} NODE_OPTIONS='--experimental-vm-modules' jest --verbose",
"test:e2e": "cd ../../packages/amplify-gen2-migration-e2e-system && npx tsx src/cli.ts --app project-boards --profile ${AWS_PROFILE:-default}",
"deploy": "cd ../../packages/amplify-gen2-migration-e2e-system && npx tsx src/cli.ts --app project-boards --step deploy --profile ${AWS_PROFILE:-default}",
"pre-push": "true",
"post-generate": "npx tsx migration/post-generate.ts",
"post-refactor": "npx tsx migration/post-refactor.ts",
Expand Down
Loading
Loading